Home > Software design >  Recursion Problem that causes a StackOverFlowError
Recursion Problem that causes a StackOverFlowError

Time:03-22

Title of the challenge in HackerRank is 'Recursive Digit Sum' I just want to know what causes my solution to have a 'StackOverFlowError'; The algorithms need to add all the digits in String n. It adds all the digits in n until the length of n is equivalent to 1. Here`s my solution in java 8.

    public static int superDigit(String n, int k) {
    // Write your code here
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < k; i  ){
            sb.append(n);
        }
        return helper(Integer.valueOf(sb.toString()));
    }
    
    public static int helper(int numbers){
        if(numbers < 10) return numbers;
        int sum = 0;
        StringBuilder sb = new StringBuilder();
        sb.append(String.valueOf(numbers));
        for(int i = 0; i < sb.length();i  ){
            sum = sum   Integer.valueOf(sb.charAt(i));
        }
        return helper(sum);
    }

CodePudding user response:

As Scott has pointed out, Integer.valueOf(sb.charAt(i)) gives you the ASCII value and not the digit itself. If you check these values, all digits have an ASCII value in 40-50s. So, for each digit, you are replacing it with a bigger number, hence your sum keeps on growing rather than diminishing.

Replace Integer.valueOf(sb.charAt(i)) with Character.getNumericValue(sb.charAt(i)) to get the correct integer value for the digit to stop the infinite recursion.

CodePudding user response:

Unfortunately, your method has other issues. I had to look up this problem to see what the goal was.

First, look at the first method. Examples I have seen are superDigit("28382", 20) which would far exceed the size of an int. So first change your method below to call helper with a string argument. You can use a loop if you wish but I would just pass the string using repeat (as of Java 11).

public static int superDigit(String n, int k) {
       // may need to check for valid values of n and k and handle accordingly
        return helper(n.repeat(k));
}

Now the helper method must accept a string. And you must return if the length of that string is <= 1. If so, convert the number to an int and return it.

Since you already have a string you don't need StringBuilder as String also has a charAt method. So now just use the technique discussed in the comments to sum the digits. You could also use sum = numbers.charAt(i) - '0';

Then you need to call helper again to check its length. So convert sum to a string and do so.

public static int helper(String numbers){
    // System.out.println(str); //uncomment this to watch
                                // your method do its job
    int sum = 0;
    if(numbers.length <= 1) {
          return Integer.parseInt(numbers);
    }
    for(int i = 0; i < numbers.length(); i  ){
        sum  =  Integer.valueOf(numbers.charAt(i)) - Integer.valueOf('0');
        // or sum  = numbers.charAt(i) - '0';
    }
    return helper(Integer.toString(sum));
}

Now you can call it like this.

int sum = superDigit("4929229", 15);
System.out.println(sum);
  • Related