3

私はついに私が望むようにそれをしました。助けてくれてありがとう。宿題ではなかったことを強調したい。

public static void main(String[] args) {
    String input = "Java is a programming language";
            StringTokenizer st = new StringTokenizer(input);
    System.out.print(longestWord(input));

}

public static String longestWord(StringTokenizer st) {
    if (!st.hasMoreTokens()) {
        return "";

    } else {
        String token = st.nextToken(); 
        String longestInTheRest = longestWord(st);
        if (token.length() > longestInTheRest.length()) { 

            return token;

        } else {
            return longestInTheRest;
        }
4

7 に答える 7

3

次のことは正しくありません。

else if (token.length() > result.length()) {

上記のステートメントを実行すると、resultは常に" "です。

関数が行うべきtokenことは、次の大きい方を返すことです。(1) ;の長さ。(2)再帰呼び出しによって返される単語の長さ。

s.substring()また、2つの呼び出しが希望どおりに機能するかどうか、または問題があるかどうかについても考えることができます。印刷しtokenrest(またはデバッガーで調べて)役立つ場合があります。

これは宿題のように見えるので、ここでやめます。

于 2012-01-15T12:48:33.593 に答える
1

現在の単語を結果と比較していますが、結果は常にに設定されているローカル変数です" "(ところで、これは空の文字列ではなく、空白を含む文字列です)。

現在の結果を引数としてメソッドに渡し、結果として空の文字列から開始する必要があります。

トークンをトリミングしないため、バグもあります。したがって、先頭の空白を単語の一部と見なします。

于 2012-01-15T12:50:44.867 に答える
1

より機能的なスタイルで書かれた別の解決策-再帰メソッドへの各呼び出しで新しい文字列を割り当てていないことに注意してください(split最初の操作のみが新しい文字列を割り当てます)。また、最初に元の問題を配列の再帰に変換するというRobertの提案を取り入れました。これにより、作業が簡単になります。

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

public static String longestWord(String[] words, int currentIdx, int longestIdx) {
    if (currentIdx == words.length)
        return words[longestIdx];
    return longestWord(words, currentIdx + 1,
        words[currentIdx].length() > words[longestIdx].length() ? currentIdx : longestIdx);
}

上記の解決策の秘訣は、私の再帰が文字列自体ではなく、文字列配列のインデックスを超えて進むことです。これが、呼び出しごとに新しい文字列を作成することを避ける理由です。、、、または同様の操作は不要でありsubstring、より洗練されたソリューションが得られます。copyOfRangearraycopynew String()

編集:

わかりやすくするために、上記のコードを少し簡略化しました。split標準の文字列操作であるメソッドについては、ドキュメントを参照してください。

public static String longestWord(String s) {        
    return longestWord(s.split(" "), 0, 0);
}

public static String longestWord(String[] words, int currentIdx, int longestIdx) {
    if (currentIdx == words.length)
        return words[longestIdx];
    int idx;  // temporarily stores the index of the current longest word
    if (words[currentIdx].length() > words[longestIdx].length())
        idx = currentIdx;
    else
        idx = longestIdx;
    return longestWord(words, currentIdx + 1, idx);
}
于 2012-01-15T14:48:00.127 に答える
0

再帰的に機能させるには、現在の状態、つまり比較する現在の最長の単語を渡す必要があります。

宿題のように見えるので、答えは含めません。そうでない場合はお知らせください。

于 2012-01-15T12:48:07.660 に答える
0
    result = token;
    return longestWord(rest);

これは間違った部分です。結果はトークンを保存しますが、メソッドを終了し、もう一度入力して結果を「」に設定します。別のパラメーターStringcurrentLongestをメソッドのシグニチャーに追加して、失われないようにします。

于 2012-01-15T12:49:02.543 に答える
0

スペースが残っているかどうかをテストする必要があります。

何かのようなもの

int index = s.indexOf(' ');
if (index < 0) return s;
于 2012-01-15T12:52:14.213 に答える
0

私はこれを解決するために少し異なるアプローチを取ります:

まず、文字列を配列に変換します。これは、再帰メソッドに適しています。

public static String longestWord(String string) {
    return longestWord(string.split(" "), "");
}

次に、再帰的な方法について考えることができます。小さい配列を再帰的に渡すと、最終的には空の配列を渡すことがわかります。これが基本ケースであり、すべての要素を列挙したので、渡された最長のものをパラメーターとして返します。再帰的な場合、(現在は小さい)配列の最初の要素が現在の最長要素よりも長いかどうかを確認し、2つのうち長い方を再帰的に渡します。

private static String longestWord(String[] strings, String currentLongest) {
    if (strings == null || strings.length == 0) {
        return currentLongest;
    }
    String[] newStrings = Arrays.copyOfRange(strings, 1, strings.length);
    String longest = strings[0].length() < currentLongest.length() ? currentLongest : strings[0];
    return longestWord(newStrings, longest);
}

注:これは、配列をコピーするのではなく、配列にインデックスを使用することによっても実現できます。ただし、実際には、これはあまりにも最適化であり、読みにくくなり、だれにもメリットがない可能性があります。

于 2012-01-15T13:48:50.950 に答える