1

So I am writing some recursive code for myself over spring break, without any purpose. Currently I am trying to make a recursive function that will reverse an inputted string from the user. I have this as of now, and it works.

import java.util.Scanner;

public class Recursion {

    public static void main(String args[]) {
        String userStr = " ", userAlt = " ";
        int position = 0, length = userStr.length() - 1;
        @SuppressWarnings("resource")
        Scanner scan = new Scanner(System.in);

        System.out.println("Please enter a string.");
        userStr = scan.nextLine();

        userAlt = reverse(userStr);
        System.out.println("\n" + userStr + " is... \n" + userAlt + " backwards!");

    }

    public static String reverse(String userStr) {
        if(userStr.isEmpty()) {
            return userStr;
        }
        else {
            return reverse(userStr.substring(1)) + userStr.charAt(0);
        }
    }
}

Although, I am unsure how this return statement works because it is confusing me. I would think that the constant output would just be the first letter at the end of the string, without fully reversing it, but it works correctly in hindsight. I was hoping someone could help me, I do not think I am missing anything with the substring() method. Thanks in advance!

For example: if the inputted string was "spring" the output of userAlt would be "gnirps", as it should be. But why?

edit: Sorry about the useless code declarations of int position & length, I was working on a different way to solve it, came across this way then never deleted the code.

1 Answers1

0

There are two parts in the following return statement:

return reverse(userStr.substring(1)) + userStr.charAt(0)

The second part, userStr.charAt(0) is the one which is getting collected into the final result.

The first part, reverse(userStr.substring(1)) is to call the function recursively with a new argument which is userStr.substring(1). This part is there simply to keep the function getting called until there is no other character is left in the parameter or in other words keep it running until all the characters are collected into the final result.

When you think of a recursive call, think of a stack (which is Last In First Out). In that sense, since O will be the last character to be pushed to the stack, it will be the first character to be out.

The simplest way to understand how a recursive method is working is to trace the values of arguments and parameters e.g.

import java.util.Scanner;

public class Recursion {

    public static void main(String args[]) {
        String userStr = " ", userAlt = " ";
        int position = 0, length = userStr.length() - 1;
        @SuppressWarnings("resource")
        Scanner scan = new Scanner(System.in);

        System.out.println("Please enter a string.");
        userStr = scan.nextLine();

        userAlt = reverse(userStr);
        System.out.println("\n" + userStr + " is... \n" + userAlt + " backwards!");

    }

    public static String reverse(String userStr) {
        if (userStr.isEmpty()) {
            System.out.println("userStr when it userStr is empty: " + userStr);
            return userStr;
        } else {
            System.out.println("userStr when userStr is not empty: " + userStr);
            System.out.println("userStr.substring(1) when userStr is not empty: " + userStr.substring(1));
            System.out.println("userStr.charAt(0) when userStr is not empty: " + userStr.charAt(0));
            return reverse(userStr.substring(1)) + userStr.charAt(0);
        }
    }
}

A sample run:

Please enter a string.
hello
userStr when userStr is not empty: hello
userStr.substring(1) when userStr is not empty: ello
userStr.charAt(0) when userStr is not empty: h
userStr when userStr is not empty: ello
userStr.substring(1) when userStr is not empty: llo
userStr.charAt(0) when userStr is not empty: e
userStr when userStr is not empty: llo
userStr.substring(1) when userStr is not empty: lo
userStr.charAt(0) when userStr is not empty: l
userStr when userStr is not empty: lo
userStr.substring(1) when userStr is not empty: o
userStr.charAt(0) when userStr is not empty: l
userStr when userStr is not empty: o
userStr.substring(1) when userStr is not empty: 
userStr.charAt(0) when userStr is not empty: o
userStr when it userStr is empty: 

hello is... 
olleh backwards!

Now you can see how 'o' + 'l' + 'l' + 'e' + 'h' = "olleh" is formed.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • So, is the point of sub stringing everything in userStr besides the first char, to return that charAt(0) (the last char in the String printed backwards) into userAlt, and then with each recursive call it moves the previous charAt up in the userAlt? Or am I not following correctly? –  Mar 25 '20 at 20:52
  • 1
    I've updated my answer with some more explanation. I hope, it helps. Feel free to comment in case of any doubt/issue. – Arvind Kumar Avinash Mar 25 '20 at 20:58
  • Oh okay, so I was getting confused with my own coding in the return statement. So the char that gets passed is the first char of userStr, in this case 'H', which then is put into userAlt and with the recursive calls it gets pushed back an index (0 to 1... 1 to 2... etc.)? The only reason I am thinking this is because a String is an array of chars, so I was not sure if adding charAt(0) was adding it at the 0th element of userAlt, or taking the 0th element from userStr. Thank you in advance for your help as well! Recursion has been confusing the heck out of me. –  Mar 25 '20 at 21:03
  • Of course I will! Just curious, that is how the String and charAt are working behind the scenes, correct? –  Mar 25 '20 at 21:10
  • 1
    Probably, you missed the following part of my answer: *When you think of a recursive call, think of a stack (which is Last In First Out). In that sense, since `o` will be the last character to be pushed to the stack, it will be the first character to be out.*. I hope, it should be clear now. Feel free to comment in case of any further doubt/issue. – Arvind Kumar Avinash Mar 25 '20 at 21:12