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"
Answer from David Webb on Stack OverflowThe 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"
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"
java - Program to reverse the words in a string - Stack Overflow
java - Using recursion to reverse a phrase - Stack Overflow
Explanation for how this recursive method to reverse a string works (JAVA)
string - Reverse the words in Java with recursively - Stack Overflow
Videos
Recursive method, using same logic as linked "duplicate", without use of split():
private static String reverseWords(String text) {
int idx = text.indexOf(' ');
return (idx == -1 ? text : reverseWords(text.substring(idx + 1)) + ' ' + text.substring(0, idx));
}
The logic is:
- Take first char/word
- If that is last char/word, return with it
- Perform recursive call with remaining text (excluding word-separating space).
- Append space (if doing word)
- Append first char/word from step 1
- Return result
As you can see, when applied to reversing text (characters) instead of words, it's very similar:
private static String reverseText(String text) {
return (text.length() <= 1 ? text : reverseText(text.substring(1)) + text.charAt(0));
}
For people who like things spelled out, and dislike the ternary operator, here are the long versions, with extra braces and support for null values:
private static String reverseWords(String text) {
if (text == null) {
return null;
}
int idx = text.indexOf(' ');
if (idx == -1) {
return text;
}
return reverseWords(text.substring(idx + 1)) + ' ' + text.substring(0, idx);
}
private static String reverseText(String text) {
if (text == null || text.length() <= 1) {
return text;
}
return reverseText(text.substring(1)) + text.charAt(0);
}
Notice how the long version of reverseText() is exactly like the version in the linked duplicate.
Recursive methods could seem a bit hard when beginning but try to do the following :
Simplify the problem as much as possible to find yourself with the less complicated case to solve. (Here for example, you could use a sentence with two words).
Begin with doing it on a paper, use Pseudocode to help you dealing with the problem with the simplest language possible.
Begin to code and do not forget an escape to your recursion.
Solution
public static void main(String[] args) {
String s = reverseSentence("This sentence will be reversed - I swear".split(" "));
System.out.println(s);
}
public static String reverseSentence(String[] sentence){
if (sentence.length <= 1){
return sentence[0];
}
String[] newArray = new String[sentence.length-1];
for (int i = 0 ; i < newArray.length ; i++){
newArray[i] = sentence[i];
}
return sentence[sentence.length-1] + " " + reverseSentence(newArray);
}
public String reverse(String str) {
if(str.length()==0){
return str;
}
else{
return reverse(str.substring(1))+str.charAt(0);
}
}I was wondering how recursive methods work. What causes this method continue to plug itself back into the function? When does str.length==0 and why does it end up returning a reversed string rather than a blank in my main method.
Do it as follows:
import java.util.Arrays;
public class Main {
public static void printReverse(String str) {
if (str == null || !str.contains(" ")) {
System.out.print(str);
return;
}
String[] words = str.split("\\s+");// Split str on space(s)
System.out.print(words[words.length - 1] + " ");// Print the last element
// Call the method recursively by passing a new string with all but last word
printReverse(String.join(" ", Arrays.asList(words).subList(0, words.length - 1)));
}
public static void main(String[] args) {
String str = "this function reverse";
printReverse(str);
}
}
Output:
reverse function this
Try this. It traverses the input string and finds out each word and then merges them into the reversed string by reversing the order of the words.
public static void printReverse (String str)
{
if ((str == null) || (str.equals("")))
return ;
str = str + " "; //to add a space at the end. this will help in detecting the last word
String revStr = "", word = "";
char c;
for (int i=0; i < str.length(); i++)
{
c = str.charAt(0);
if (c != ' ')
{
word = word + c;
}
else
{
revStr = word + " " + revStr;
}
}
System.out.println(revStr.Trim()); //removes the extra space from the end
}
}