Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid StackOverFlow in recursion?

I need to find the frequency of each character in a String using recursion. Found this question online and wanted to do this as a challenge.

Have used two variables 'a' and 'i', where 'a' is used to store the index of the current character in the string that needs to be searched and 'i' is used to go through the entire string in search of the character that 'a' has extracted.

Finding the frequency of each character present in the word.

import java.util.*;
public class ini {

    public static void main(String args[]) {
        recur(0, 0, "Hello how are you", 0);
    }

    static private char m = ' ';

    private static boolean recur(int a, int i, String s, int count) {
        if (s.length() >= 1) {
            if (a < s.length()) {
                m = s.charAt(a);
                if (i < s.length()) {
                    if (s.charAt(a) == s.charAt(i)) {
                        count += 1;
                    }
                    recur(a, ++i, s, count);
                }
                i = 0;
                System.out.println(s.charAt(a) + ":" + count);
                s = s.replaceAll(Character.toString(s.charAt(a)), "");
                a += 1;
                count = 0;
            }
            if (a != s.length() - 1) {
                recur(a, i, s, count);
            }
        } else {
            return false;
        }
        return true;
    }
}

The current output ignores the letter "w" altogether

H:1
l:2
 :3
o:3
r:1
y:1
Exception in thread "main" java.lang.StackOverflowError
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at ini.recur(ini.java:26)
at...
like image 211
lafeo_007 Avatar asked Mar 03 '23 14:03

lafeo_007


1 Answers

There are a couple of things that we don't know:

  1. Should h and H be considered only one character?
  2. Should you count the spaces? (Programmatically speaking, space is a character)
  3. Do you need an improved solution?
  4. Are you allowed to do manipulate the initial text?

Some observations:

  1. You need to rename your variables better
  2. You don't need the static field
  3. You don't need the recursive function to be boolean
  4. a is used only for the identification of the character, and the increment is not needed

Quick solution:

private static void recur(int startingIndex, int recursionIndex, String text, int count) {
    if (text.length() >= 1) {
        if (startingIndex < text.length()) {

            char currentCharacter = text.charAt(startingIndex);

            if (recursionIndex < text.length()) {
                if (currentCharacter == text.charAt(recursionIndex)) {
                    count += 1;
                }

                recur(startingIndex, ++recursionIndex, text, count);
            } else {
                System.out.println(currentCharacter + ":" + count);
                text = text.replace(Character.toString(currentCharacter), "");

                recur(0, 0, text, 0);
            }
        }
    }
}

Improved solution:

public class Main {
    public static void main(String[] args) {
        recur(0, "Hello how are you", 0);
    }

    private static void recur(int index, String text, int count) {
        if (text.length() >= 1) {
            char currentCharacter = text.charAt(0);

            if (index< text.length()) {
                if (currentCharacter == text.charAt(index)) {
                    count += 1;
                }

                recur(++index, text, count);
            } else {
                System.out.println(currentCharacter + ":" + count);
                text = text.replace(Character.toString(currentCharacter), "");

                recur(0, text, 0);
            }
        }
    }
}

The optimal solution without modifying the initial text:

private static int recur(char character, String text, int index) {
    if (index >= text.length()) {
        return 0;
    }

    int count = text.charAt(index) == character? 1 : 0;
    return count + recur(text, character, index + 1);
}
like image 142
LoolKovsky Avatar answered Mar 12 '23 00:03

LoolKovsky