49

Here is some Java code to reverse a string recursively.

Could someone provide an explanation of how it works?

public static String reverse(String str) {
    if ((null == str) || (str.length() <= 1)) {
        return str;
    }
    return reverse(str.substring(1)) + str.charAt(0);
}

I'm not understanding how this can possibly work.

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Bob Sanders
  • 4,317
  • 4
  • 18
  • 11
  • 18
    It's homework, @DwB - I think it's a reasonable demonstration of recursion. – adelphus Mar 15 '12 at 16:37
  • @DwB it has a homework tag, so they are probably using it to teach recursion. Its one of the easiest ways to understand how recursion works the first time – jzworkman Mar 15 '12 at 16:38
  • It didn't have the homework tag when I added the comment. – DwB Mar 15 '12 at 16:39
  • 1
    @DwB Sorry DwB, you are right, I did not have a homework tag on it. This isn't necessarily for an real world application, it was just for me to understand what exactly is going on in this example of recursion. – Bob Sanders Mar 15 '12 at 20:38
  • I got asked this today and I think I was supposed to come up with what you wrote. What I did come up with was this http://pastebin.com/r4B3xEMe More code, but a reverses in half the calls. – Peter Turner Jan 15 '15 at 22:45
  • @PeterTurner, were you asked to do it in Delphi or you chose that? Interesting language choice for such a question. – David Mar 05 '15 at 05:37
  • @david, I got asked it in an interview for a place where I'll be programming on java when I'd been programming Delphi for the last 8 years. – Peter Turner Mar 05 '15 at 14:37
  • @PeterTurner, interesting, and how did that turn out for that particular question session? I assume the interviewer may not have been familiar with Delphi. – David Mar 09 '15 at 19:02
  • @DwB why its bad i got and interview main question about this but in c++ even i am a java developer .? – shareef Jul 15 '15 at 17:45
  • I have already answered the [here](http://stackoverflow.com/questions/13150131/java-recursively-reverse-an-array) – Arjun Thakur Nov 26 '15 at 07:02
  • This will not reverse a String, because you can not reverse a String by arranging its char values in reverse order. UTF-16 does not work that way as an encoding of code points. And then there is the difficulty of diacritic modifier characters. – Raedwald Dec 13 '17 at 18:05
  • This could always be a challenge from Codewars.com or Leetcode.com, I would not just assume it is homework. Things like leetcode after a certain period of time being stuck, it is acceptable to look up an answer, at that point in time, one would want to get to where they can understand the answer and how and why it works. – Josepch Mar 02 '22 at 01:59

18 Answers18

104

The function takes the first character of a String - str.charAt(0) - puts it at the end and then calls itself - reverse() - on the remainder - str.substring(1), adding these two things together to get its result - reverse(str.substring(1)) + str.charAt(0)

When the passed in String is one character or less and so there will be no remainder left - when str.length() <= 1) - it stops calling itself recursively and just returns the String passed in.

So it runs as follows:

reverse("Hello")
(reverse("ello")) + "H"
((reverse("llo")) + "e") + "H"
(((reverse("lo")) + "l") + "e") + "H"
((((reverse("o")) + "l") + "l") + "e") + "H"
(((("o") + "l") + "l") + "e") + "H"
"olleH"
David Webb
  • 190,537
  • 57
  • 313
  • 299
20

You need to remember that you won't have just one call - you'll have nested calls. So when the "most highly nested" call returns immediately (when it finds just "o"), the next level up will take str.charAt(0) - where str is "lo" at that point. So that will return "ol".

Then the next level will receive "ol", execute str.charAt(0) for its value of str (which is "llo"), returning "oll" to the next level out.

Then the next level will receive the "oll" from its recursive call, execute str.charAt(0) for its value of str (which is "ello"), returning "olle" to the next level out.

Then the final level will receive the "oll" from its recursive call, execute str.charAt(0) for its value of str (which is "hello"), returning "olleh" to the original caller.

It may make sense to think of the stack as you go:

// Most deeply nested call first...
reverse("o") -> returns "o"
reverse("lo") -> adds 'l', returns "ol" 
reverse("llo") -> adds 'l', returns "oll" 
reverse("ello") -> adds 'e', returns "olle" 
reverse("hello") -> adds 'h', returns "olleh" 
shmosel
  • 49,289
  • 6
  • 73
  • 138
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I think this is the correct simple explanation and not the one accepted because recursive call will be evaluated first and then "str.charAt(0)". it will be better understood by splitting the last line into two lines "String ab = reverse(str.substring(1)); return ab + str.charAt(0);" – Jayesh Mar 07 '16 at 05:17
4

Run it through a debugger. All will become clear.

Dave
  • 4,546
  • 2
  • 38
  • 59
  • 3
    "by far, the best answer"? So why did it get 0? And why do people keep saying to watch it run on such long strings? And under what circumstances does it terminate on "null==str"? Even a newly created String object does not do this. What is the length of a null String object, after all? – Matt J. Mar 14 '13 at 01:58
2

Inline sample;

public static String strrev(String str) {
    return !str.equals("") ? strrev(str.substring(1)) + str.charAt(0) : str;
}
Fatih Mert Doğancan
  • 1,016
  • 14
  • 21
2

Because this is recursive your output at each step would be something like this:

  1. "Hello" is entered. The method then calls itself with "ello" and will return the result + "H"
  2. "ello" is entered. The method calls itself with "llo" and will return the result + "e"
  3. "llo" is entered. The method calls itself with "lo" and will return the result + "l"
  4. "lo" is entered. The method calls itself with "o" and will return the result + "l"
  5. "o" is entered. The method will hit the if condition and return "o"

So now on to the results:

The total return value will give you the result of the recursive call's plus the first char

To the return from 5 will be: "o"

The return from 4 will be: "o" + "l"

The return from 3 will be: "ol" + "l"

The return from 2 will be: "oll" + "e"

The return from 1 will be: "olle" + "H"

This will give you the result of "olleH"

jzworkman
  • 2,695
  • 14
  • 20
2

Run the code below - it prints:

Step 0: ello / H
Step 1: llo / e
Step 2: lo / l
Step 3: o / l
Step 3 returns: ol
Step 2 returns: oll
Step 1 returns: olle
Step 0 returns: olleH

Code:

public class Test {

    private static int i = 0;

    public static void main(String args[]) {
        reverse("Hello");
    }

    public static String reverse(String str) {
        int localI = i++;
        if ((null == str) || (str.length()  <= 1)) {
            return str;
        }
        System.out.println("Step " + localI + ": " + str.substring(1) + " / " + str.charAt(0));
        String reversed = reverse(str.substring(1)) + str.charAt(0);

        System.out.println("Step " + localI + " returns: " + reversed);
        return reversed;
    }
}
assylias
  • 321,522
  • 82
  • 660
  • 783
0

Best Solution what I found.

public class Manager
{
    public static void main(String[] args)
    {
        System.out.println("Sameer after reverse : " 
                         + Manager.reverse("Sameer"));
        System.out.println("Single Character a after reverse : " 
                         + Manager.reverse("a"));
        System.out.println("Null Value after reverse : "
                         + Manager.reverse(null));
        System.out.println("Rahul after reverse : "
                         + Manager.reverse("Rahul"));
    }

    public static String reverse(String args)
    {
        if(args == null || args.length() < 1 
                                || args.length() == 1)
        {
            return args;
        }
        else
        {
                return "" + 
                               args.charAt(args.length()-1) + 
                               reverse(args.substring(0, args.length()-1));                                  
        }
    }
}

Output:C:\Users\admin\Desktop>java Manager Sameer after reverse : reemaS Single Character a after reverse : a Null Value after reverse : null Rahul after reverse : luhaR

Vicky K
  • 1
  • 1
0
public class ReverseString{

private static  String reverse(String text, String reverseStr){
    if(text == null || text.length() == 0){
        return reverseStr;
    }
    return reverse(text.substring(1), text.charAt(0)+reverseStr);
}
public static void main(String [] args){
    System.out.println(reverse("hello", "")); //output is "olleh"
}

}

0

Another Solutions for reversing a String in Java.

Convert you string into a char array using .toCharArray() function.

public static char[] reverse(char in[], int inLength, char out[],
            int tractOut) {

        if (inLength >= 0) {
            out[tractOut] = in[inLength];
            reverse(in, inLength - 1, out, tractOut + 1);
        }

        return null;

    }
Rakesh Chaudhari
  • 3,310
  • 1
  • 27
  • 25
0
class Test {
   public static void main (String[] args){
      String input = "hello";
      System.out.println(reverse(input));
    }

    private static String reverse(String input) {
        if(input.equals("") || input == null) {
        return "";
    }
    return input.substring(input.length()-1) + reverse(input.substring(0, input.length()-1));
} }

Here is a sample code snippet, this might help you. Worked for me.

Kaustubh
  • 653
  • 6
  • 21
0
import java.util.*;

public class StringReverser
{
   static Scanner keyboard = new Scanner(System.in);

   public static String getReverser(String in, int i)
   {
      if (i < 0)
         return "";
      else
         return in.charAt(i) + getReverser(in, i-1);
   }

   public static void main (String[] args)
   {
      int index = 0;

      System.out.println("Enter a String");
      String input = keyboard.nextLine();


      System.out.println(getReverser(input, input.length()-1));
   }
}
Chris Zog
  • 13
  • 6
0

AFAIK, there 2 thing in every recursion function :

  1. There is always a stop condition which is :

    if ((null == str) || (str.length() <= 1)) { return str; }

  2. Recursion use the stack memory which use LIFO mechanism that's why the revert happen.

TooCool
  • 10,598
  • 15
  • 60
  • 85
0
`public class reverseString {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    
    String  brr= "momo";
    int n=brr.length()-1;
    
    string_Finder(brr,n);
     
}
 public static void string_Finder(String arr,int n) {
      
       if(n==0) {
           System.out.println(arr.charAt(0));
       }else {
           System.out.println(arr.charAt(n));
           
           string_Finder(arr,n-1);
       }
       
       }

}`

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 11 '23 at 16:42
0

Take the string Hello and run it through recursively.

So the first call will return:

return reverse(ello) + H

Second

return reverse(llo) + e

Which will eventually return olleH

len
  • 335
  • 1
  • 5
0

The call to the reverce(substring(1)) wil be performed before adding the charAt(0). since the call are nested, the reverse on the substring will then be called before adding the ex-second character (the new first character since this is the substring)

reverse ("ello") + "H" = "olleH"
--------^-------
reverse ("llo") + "e" = "olle"
---------^-----
reverse ("lo") + "l" = "oll"
--------^-----
reverse ("o") + "l" = "ol"
---------^----
"o" = "o"

PATRY Guillaume
  • 4,287
  • 1
  • 32
  • 41
0

run the following and you'll see what's going on:

public class RS {

    public static String reverse(String str) {
        System.out.println("--- reverse --- " + str);
        if ((null == str) || (str.length() <= 1)) {
            return str;
        }
        return add(reverse(str.substring(1)), charAt(str));
    }

    public static char charAt(String s) {
        System.out.println("--- charAt --- " + s);
        return s.charAt(0);
    }

    public static String add(String s, char c) {
        System.out.println("--- add --- " + s + " - " + c);
        return s + c;
    }

    public static void main(String[] args) {
        System.out.println("start");
        System.out.println("result: " + reverse("hello"));
        System.out.println("end");
    }

}
10 Replies
  • 426
  • 9
  • 25
Tom
  • 4,096
  • 2
  • 24
  • 38
-1
import java.util.Scanner;

public class recursion{
    public static void main (String []args){

    Scanner scan = new Scanner(System.in);
    System.out.print("Input: ");
    String input = scan.nextLine();

    System.out.print("Reversed: ");
    System.out.println(reverseStringVariable(input));

    }public static String reverseStringVariable(String s) {
        String reverseStringVariable = "";

        for (int i = s.length() - 1; i != -1; i--) {
            reverseStringVariable += s.charAt(i);

        }

        return reverseStringVariable;
    }
}
Remi Guan
  • 21,506
  • 17
  • 64
  • 87
mymy
  • 1
-2

Try this:

public static String reverse(String str) {
   return (str == null || str.length()==0) ? str : reverseString2(str.substring(1))+str.charAt(0);
}
vikash
  • 381
  • 2
  • 11