4

Just to practice recursion, I wrote one of the classic intro recursive functions - one that checks if a given string is a palindrome.

My question is: within the first if statement, why do I have to write return palChecker(...) as opposed to just palChecker(...)? It seems to me the function should work without that first return statement. But from testing I know that's not true, but I'm not really clear on why.

(Btw, the print statements are just there so I could see what was going on during testing. I like actually seeing each executed line.)

public static boolean palChecker(String s){
    if ( s.charAt(0)==s.charAt(s.length()-1) && s.length()>1){
        System.out.println(s);
        return palChecker(s.substring(1,s.length()-1)); //why do i need the return here?
    }
    else if (s.length()==1 || s.length()==0){
        System.out.println(s);
        return true;
    }
    return false;
}
Pokechu22
  • 4,984
  • 9
  • 37
  • 62

3 Answers3

5

You need to return the value eventually returned by PalChecker.

The definition of a Java function is that it always returns a value ... even if it is a chain from the deepest point in your recursion, bringing true or false finally to the top.

hichris123
  • 10,145
  • 15
  • 56
  • 70
ErstwhileIII
  • 4,829
  • 2
  • 23
  • 37
3

If you were missing return palChecker, then it will never return true unless s is length 0 or 1. Because when palChecker recursively discovers the answer is true, there is no way for it to return that discovery back to you; it will just go to the return false line when the recursion returns.

  1. palChecker("ABCBA") executes palChecker("BCB")
  2. palChecker("BCB") executes palChecker("C")
  3. palChecker("C") executes return true
  4. palChecker("BCB") receives that true but if you are missing the return statement, it does not return it; it moves to the next line of code which is return false
  5. palChecker("ABCBA") receives that false but if you are missing the return statement, it moves to the next line of code which is return false
  6. final result is false

It is more clear if you can rewrite with explicit else.

public static boolean palChecker(String s){
    if (s.length()==1 || s.length()==0){
        System.out.println(s);
        return true;
    }
    // at this point s.length() > 1
    if (s.charAt(0)==s.charAt(s.length()-1)){
        System.out.println(s);
        return palChecker(s.substring(1,s.length()));
    }
    else { 
        // mismatch
        return false;
    }
}
Apprentice Queue
  • 2,036
  • 13
  • 13
  • Okay thank you. Although I'm still a little unclear on why the method without the return statement would always return false as opposed to messing up in a different way. Let's say I do: palChecker("aa"). I expect this to happen: palChecker("aa") = palChecker(palChecker("")) = palChecker(true) Am I right that once it reaches the bottom and starts going backwards palChecker is getting a boolean passed to it? Why doesn't it mess up because this is the wrong type. I think I'm imagining how this function executes incorrectly. What is the correct sequence of steps? – yellowFreet Sep 07 '14 at 17:16
  • You are partially right, except you seem to think that returned value are passed as arguments to your method while going backwards palChecker calls. This is not how it works, the returned value is simply returned to the caller *and the normal flow of the function continues*. – m4rtin Sep 07 '14 at 17:55
  • @m4rtin I don't understand what you are saying. I am exactly saying "the normal flow of the function continues" and in the OP's code, that means returning false. – Apprentice Queue Sep 07 '14 at 19:13
  • @ApprenticeQueue Sorry you thought my comment was meant to you, I was really just responding to user3171562's comment :) I think your answer is as good as mine ;) – m4rtin Sep 07 '14 at 19:17
-1

Without this return statement, your palChecker would almost always return false.

Think about it, the function would indeed be executed recursively but in the end, it would just either just return a true or false value that you wouldn't use, the program would then go back up the call stack only returning false ultimately making your method always returning false (except if s.length()==1 || s.length()==0 is true on first call).

m4rtin
  • 2,445
  • 22
  • 34