Home > Back-end >  What am I missing in this recursion?
What am I missing in this recursion?

Time:09-28

So I am trying to recursive print all the sum of odd digits in a number. Like the number 12345 would be 9 This code does not work, but I do not understand why.

public static int oddSum(int n){
            String nn = Integer.toString(n);
            if(nn.length()==1 && Integer.parseInt(nn)%2==1) {
                return Integer.parseInt(nn);
            } else if(nn.length()==1 && Integer.parseInt(nn)%2==0) {
                return 0;
            }
            if((int)nn.charAt(0)%2 == 1) {
                return oddSum(Integer.parseInt(nn.substring(1)) (int)nn.charAt(0));
            } else {
                return oddSum(Integer.parseInt(nn.substring(1)));
            }
        }

CodePudding user response:

I kinda feel like this is a homework problem, but I'll bite.

I don't specifically know java, so I can't comment on the details of the code. But, if I'm reading it correctly, it seems like you're taking an integer, converting it to a string, stripping characters and returning them to integers to process? That seems convoluted.

What about this pseudo-code?

int oddSum(n)
{
    if (n < 10)
    {
        if (n%2 == 1)
            return n
        else
            return 0
    }
    return oddSum(n/10)   oddSum(n)
}

CodePudding user response:

The root cause? You don't know how to debug, apparently.

The direct cause?

return oddSum(Integer.parseInt(nn.substring(1)) (int)nn.charAt(0));

This line is buggy. You're invoking oddSum on:

  • Take the input number. Lop off the first digit.
  • Now add to that (numerically, not string concat), the ASCII code of the first character.

For input 12345 that means: 2345 49 = 2394, which makes no sense whatsoever. What you probably intended to do is:

  • Take the input number. Lop off the first digit. Feed that to oddSum.
  • Take whatever this recursive call to oddSum returns, and add the actual value of the digit to it (and not its ASCII code).

That's not what your line does - your parentheses are entirely in the wrong place, and (int) nn.charAt(0) does not get you the value of the first digit. It gets you the ASCII code of it. 0 is 48, 1 is 49, and so on.

To turn an ascii character into its digit value, you can do it 'mathematically':

int valueOfFirstDigit = nn.charAt(0) - '0';

This works because all 9 digits show up, in order, in the ASCII table. So, subtracting the ASCII value of the 0 character gives you 0, '1' - '0' is 1, etcetera.

Keep in mind, character like 'a' all turn into numbers in the computer's memory. So, which number? That's what the ASCII table is all about. The character '0' does not turn into the number 0 in the system; it turns into 48, which is the ASCII code of the character '0'. Keep in mind, 0 the number is not at all equal to '0' the character.

Fix the parentheses issue, and fix your confusion between ASCII and int, and your take will work fine.

Debugging?

Your root cause here is that you need to debug code. Coding isn't actually like the movies. You don't just code something and get it right in one go, nor do you fix any problems with code by dramatically and intently staring at it.

You debug.

Debugging is simple. Line for line you figure out in your head what the code should be doing, and then you run the code and contrast what you think it should be doing, with what it is actually doing. Anytime you find a discrepancy, great. You found 1 bug. Fix it, and keep going, because bugs are herd animals.

Debuggers let you do this - they give you tools to step through (run 1 line, and pause until you press the button to run the next line), and give you eyes on the values of whatever variables you care about, letting you do the job of checking what is actually going on, so that you can compare it to what you think should be happening.

If learning to use a debugger is a bridge too far, there's always the option to just toss a cavalcade of System.out statements at your code: Add one in between every line, printing the values of all relevant variables and results of all relevant expressions, and you just wasted a ton of time to recreate the abilities of a debugger. But, you don't have to learn how to use one, so I guess it's an option. Though I'd just learn how to use a debugger.

had you done that, you'd have figured this out on your own, I bet.

CodePudding user response:

The more efficient way of doing this is to trim the number one digit at a time. You are using a string and the concatenation in your return statements are returning incorrect results.

Example of recursion:

n = 123
n % 10 will give you 3
n = n / 10 will trim the 3
n != 0, so call oddSum(12)   3 [We add the 3 to call because it is odd]

n = 12
n % 10 will give you 2
n = n / 10 will trim the 2
n != 0, so call oddSum(1) [We don't add the 2 since it is even]

n = 1
n % 10 will give you 1
n = n / 10 will give you 0
return oddSum(0)   1 [add this odd digit]

Since n == 0 -> base case reached, so the recursion stops [return 0]
Sum of all recursions will be 4.
public class SumOfOddDigits {
    
    public static int oddSum(int n) {
        /* Base case to exit recursion */
        if(n <= 0) {
            return 0;
        }
        /* Ternary statement that checks if the last digit is odd */
        /* If so, call oddSum(n) and add the odd digit */
        /* 'n' will be divided by 10 and passed into oddSum recursively */
        return (n % 10) % 2 == 1 ? oddSum(n / 10)   (n % 10) : oddSum(n /10);
    }
    
    public static void main(String[] args) {
        System.out.println(oddSum(12345));
    }
}

CodePudding user response:

If anyone is curious

public static int oddSums(int n){
            if(n<10) {
                if(n%2==1) {
                    return n;
                } else {
                    return 0;
                }
            }
            if((n)%2 == 1) {
                return oddSums(n/10) (n&10);
            } else {
                return oddSums(n&10);
            }

            
        }
  • Related