简体   繁体   中英

Could someone please explain the algorithm of reverse string using tail recursion?

I am sorry for being stupid to ask this question. I able to understand the code until getting the last character of the given string and return, then I am not able to relate the recursion logic.

Before posting it here, debugger helped me partially. Unfortunately, not 100%

Could you please help me to understand this?

public static void main(String[] args) {
    System.out.println(reverseRecursively("abcd"));
}

public static String reverseRecursively(String str) {
    if (str.length() < 2) {
        return str;
    }
    return reverseRecursively(str.substring(1)) + str.charAt(0);
}

Debugger Output:

0=abcd
1=bcd
2=cd
3=d
Final: dcba

Well, it's a pretty simple logic:

return reverseRecursively(str.substring(1)) + str.charAt(0);

If you put a System.out.println() before the return, you'll get the following output:

Recursing with substring: bcd and adding a
Recursing with substring: cd and adding b
Recursing with substring: d and adding c
Adding d as final char

If you reverse this, you get dcba .

Why is it reversed though?

Well, you have to think of the call trace:

return reverseRecursively("bcd") + a -> retruns "dcba"
-> return reverseRecursively("cd") + b -> returns "dcb"
 -> return reverseRecursively("d") + c -> returns "dc"
   -> return d -> returns "d"

I guess the key point is to understand that the recursion is always combined with the result of another recursion.

When the method runs, it will check first if the String is one or zero characters in length. This will tell it whether it is the final character in the string. If not, it will append the current character to the end of the string and run again, this time on the next character along. This means that the string gets a character shorter every time.

What may be confusing is that the str.charAt(0) is not passed into the next iteration of the method, rather just added as a part of the return statement. This means that once the method has completed the final character, it will return all characters in backwards order as each method completes one after the other starting with the one that returns the last character. This will happen until all methods return and returns your reversed string.

It's like layers of methods, one will invoke another and then they will all complete in backwards order to the order in which they were called.

Hope this helped your understanding!

No question is stupid question. If one doesn't ask a question, thinking that people will think he/she is stupid, then he/she is stupid for life. :)

Now the explanation:

I added a print statement to help you with it.

public static String reverseRecursively(String str) {
    System.out.println("For debuging : "+str); // this is my print statement.
    if (str.length() < 2) {
        return str;
    }
    return reverseRecursively(str.substring(1)) + str.charAt(0);
}

It prints the below.

    For debuging : abcd
    For debuging : bcd
    For debuging : cd
    For debuging : d
    dcba

The base criteria for the method to return the value is, str.length() < 2 .

So when the "d" is returned by last method call(or we can say the fourth method call to reverseRecursively(String str) ), because the length is less than 2. The third method call will return

"d" + "cd".charAt(0);

which is nothing but : dc.

Similary 2nd method will use the third method's return value (dc) and return the value

"dc" + "bcd".charAt(0);

which is dcb.

and so the first method call, where you passed the string "abcd" as input will return.

"dcb" + "abcd".charAt(0);

which is dcba.

Hope this helps. Cheers !!!

`public static String reverseRecursively(String str) {
    if (str.length() < 2) {
        return str;
    }
    return reverseRecursively(str.substring(1)) //take "bcd" : 1st Itration
                                                //"cd" : 2nd 
                                                // "d" : 3rd (this makes str.length() < 2)
 // 3rd returns first with "d" and pass control back to 2nd recursion
 //2nd takes d and adds 0th char c and returns with "dc" and pass control to 1st
 //1st takes dc and adds b returns with "dcb" and pass control to base call
 // base call take "dcb" and adds 0th char a and returns to calling method
+ str.charAt(0);
}`. 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM