2017-02-28 111 views
1

我想通过使用递归来反转字符串单词。 (例如:“你好我的朋友”与“朋友我的你好”相反)这是我为此方法试图编写的代码。我尝试了多个类似的变体,但输出只是字符串的第一个或最后一个单词。我相信那个被“破碎”的部分是第一个陈述,但我不太确定。使用递归来反转字符串

public static String reverse (String words) { 
    Scanner sc = new Scanner(words); 
    String backwards = ""; 

    if (sc.hasNext()) { 
    String currentWord = sc.next(); 
    reverse(sc.nextLine()); 
    backwards = backwards + " " + currentWord; 
    } //end if 
    else { 
    backwards = words; 
    } //end else 

    return backwards; 
} 

我知道存在一些类似的问题,但他们的答案似乎并没有帮助我理解我的错误。

谢谢!

+0

你不节能递归调用的结果。 –

+0

我要去看看,谢谢! @JornVernee – Gabbie

+0

我没有用StringBuilder工作太多,我会研究它! @OusmaneDiaw – Gabbie

回答

3

而不是使用Scanner,你可以利用String.split过载的分裂words围绕第一空间:

public static String reverse(String words) { 
    String[] wordArr = words.split(" ", 2); // split into a maximum of 2 Strings 

    if (wordArr.length > 1) { // If there is more than 1 word 
     // return the first word (wordArr[0]), 
     // behind the reverse of the rest of the String (wordArr[1]) 
     return reverse(wordArr[1]) + " " + wordArr[0]; 
    } 

    return wordArr[0]; // else, just return the one word 
} 
+0

这解决了我的问题,很简单,很好地解释,谢谢! :) – Gabbie

0

您是否必须使用递归?没有它你可以做到这一点。

public static String reverse(String words) { 
    String[] list = words.split(" "); 
    Collections.reverse(list); 
    String reversed = String.join(" ", list); 
    return reversed; 
} 
+0

感谢您的输入,但我必须使用递归:) – Gabbie

1

如评论中所述,您可以使用StringBuilder而不是Scanner类。

本示例发送相同的单词,每当您输入方法时将它们分隔空格,并发送要在下一次迭代中添加的单词的索引。

例如:

public class RecursiveReverse { 

    static StringBuilder sb = new StringBuilder(); 

    public static void main(String[] args) { 
     String stringToReverse = "Hello my friend!"; 
     System.out.println(reverse(stringToReverse, stringToReverse.split(" ").length - 1)); 
    } 

    public static String reverse(String words, int i) { 
     if (i >= 0) { //If the index of the words is greater or equals the first word 
      sb.append(words.split(" ")[i]); //We split it and append it to our StringBuilder 
      sb.append(" "); //We append a space 
      reverse(words, --i); //We do this again 
     } 
     return sb.toString(); //When the above condition doesn't match we return the StringBuilder object as a String (which contains the words reversed) 
    } 
} 

将会产生以下输出:

friend! my Hello 

更好的方法将被传递一个字符串数组作为参数,以便你分割只有一次(发送词语作为阵列时该方法)字符串。

public class RecursiveReverse { 

    static StringBuilder sb = new StringBuilder(); 

    public static void main(String[] args) { 
     String stringToReverse = "Hello my friend!"; 
     String words[] = stringToReverse.split(" "); 
     System.out.println(reverse(words, words.length - 1)); 
    } 

    public static String reverse(String words[], int i) { 
     if (i >= 0) { 
      sb.append(words[i]); 
      sb.append(" "); 
      reverse(words, --i); 
     } 
     return sb.toString(); 
    } 
} 
1

你扔掉的递归结果:

reverse(sc.nextLine()); 
backwards = backwards + " " + currentWord; 

相反,使用这样的:

backwards = reverse(sc.nextLine()); 
backwards = backwards + " " + currentWord; 

更妙的是:

backwards = reverse(sc.nextLine()) + " " + currentWord; 
+0

我刚刚尝试过这个建议,我得到一个NoSuchElementException,任何想法为什么? – Gabbie

+0

如果您可以用[MCVE](http://stackoverflow.com/help/mcve)发布问题,我会查看它。您当前的代码不足以执行问题点。 – Prune

+0

我想我明白了。您正在寻找下一行,而不是扫描当前行的剩余部分。维修:像其他人所建议的一样,将扫描仪完全倾倒,只处理字符串包。找到下一个空格,在该点分成两个子字符串,并在字符串的其余部分重复出现。 – Prune

0

你必须保持所提取的保持累加器中的调用之间的词。这是一个例子。

public static String reverse(String words, String acc){ 
    Scanner sc = new Scanner(words); 

    if(!sc.hasNext()){ 
     return acc; 
    } 

    return reverse(sc.nextLine(), acc) + " " + sc.next(); 
} 

你会这样称呼它。

reverse("Hello my friend", ""); 

这不是世界上最高效的实现,但是......它必须工作!

如果您想要更高效的方法,请使用StringBuilder作为累加器。

4

您不应该致电nextLine(),因为您的输入全部在一行上。如果你开始创建一个简单的帮助器方法,你的逻辑就更清晰了,它应该有一个words的数组和一个位置;从那里,你可以递归构建的东西你想要的输出像

private static String reverse(String[] words, int p) { 
    if (p + 1 < words.length) { 
     return reverse(words, p + 1) + " " + words[p]; 
    } else if (p < words.length) { 
     return words[p]; 
    } 
    return ""; 
} 

那么你public方法很容易实现,只需split在白色空间中的原始输入,并呼吁reverse开始0(记住要return结果)。像,

public static String reverse(String words) { 
    return reverse(words.split("\\s+"), 0); 
} 

然后,我测试它像

public static void main(String[] args) { 
    System.out.println(reverse("Hello my friend")); 
} 

其输出(如需要)

friend my Hello 

或者,你能有这样的助手把你Scanner,而不是像

private static String reverse(Scanner sc) { 
    if (sc.hasNext()) { 
     String currentWord = sc.next(); 
     if (sc.hasNext()) { 
      return reverse(sc) + " " + currentWord; 
     } 
     return currentWord; 
    } 
    return ""; 
} 

然后你的公开法

public static String reverse(String words) { 
    return reverse(new Scanner(words)); 
}