2017-02-28 107 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)); 
}