簡體   English   中英

使用遞歸反轉字符串

[英]Using Recursion to Reverse a String

我正在嘗試使用遞歸逐字反轉字符串。 (例如:“你好我的朋友”被顛倒為“朋友我的你好”)這是我試圖為這個方法編寫的代碼。 我嘗試了多個類似的變體,但輸出只是字符串的第一個或最后一個單詞。 我相信“損壞”的部分是第一個 if 語句,但我不太確定。

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;
 }

我知道存在一些類似的問題,但他們的回答似乎並沒有幫助我理解我的錯誤。

謝謝!

你不應該調用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原始輸入並從0開始調用reverse (記住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));
}

您可以使用String.split的重載來分割第一個空格周圍的words ,而不是使用Scanner

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
}

如評論中所述,您可以使用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 

更好的方法是將 String 數組作為參數傳遞,這樣您只需將字符串拆分一次(將單詞作為數組發送到方法時)。

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();
    }
}

你扔掉遞歸結果:

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

相反,使用這個:

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

更好的是:

 backwards = reverse(sc.nextLine()) + " " + currentWord;
public static String reverseSentence(String sentence) {

    StringBuilder sb = new StringBuilder();

    int firstSpace = sentence.indexOf(' ');
    if (firstSpace == -1) {
        return sb.append(sentence.strip()).append(" ").toString();
    }
    String secondPart = sentence.substring(firstSpace + 1); 
    String firstPart = sentence.substring(0, firstSpace);//similar to merger sort 
    return sb.append(reverseSentence(secondPart)).append(reverseSentence(firstPart)).toString();
}

你必須使用遞歸嗎? 沒有它你也能做到。

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

您必須在累加器中保持調用之間提取的單詞。 這是一個例子。

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作為累加器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM