2

クラスワードを作成しました。Word には、文字列引数を取るコンストラクタと、長さでソートされた word のすべての部分文字列を含む文字列を返す 1 つのメソッド getSubstrings があります。

たとえば、ユーザーが「rum」と入力すると、メソッドは次のように出力される文字列を返します。

r
u
m
ru
um
rum 

文字列内の部分文字列を連結し、改行 ("\n") で区切りたいと考えています。次に、文字列を返します。

コード:

    public class Word {
    String word;

    public Word(String word) {
        this.word = word;
    }
    /**
     * Gets all the substrings of this Word.
     * @return all substrings of this Word separated by newline
     */

    public String getSubstrings()
    {
        String str = "";
        int i, j;
        for (i = 0; i < word.length(); i++) {
            for (j = 0; j < word.length(); j++) {
                str = word.substring(i, i + j);
                str += "\n";
            }
        }
        return str;
    }

しかし、それは例外をスローします:

java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:1911)

この時点で立ち往生しました。たぶん、このメソッドの署名に従って他の提案がありますpublic String getSubstrings()
この問題を解決するには?

4

3 に答える 3

6

例外の分析:

StringIndexOutOfBoundsException の Java7 ドキュメントから

public class StringIndexOutOfBoundsException extends IndexOutOfBoundsException

インデックスが負であるか、文字列のサイズより大きいことを示すために、String メソッドによってスローされます。

部分文字列のJava 7ドキュメントから

public String substring(int beginIndex,int endIndex)

この文字列の部分文字列である新しい文字列を返します。部分文字列は、指定された beginIndex で始まり、インデックス endIndex - 1 の文字まで拡張されます。したがって、部分文字列の長さは endIndex-beginIndex になります。

私はこれを推測します: 部分文字列の長さは endIndex-beginIndexになりString index out of range: -1ます。私は、私の仮定が正しいと仮定して複数のケースでテストしましたが、他の証拠に感謝します.

-1の場合: "rum".substring(2,1);あなたに与えますString index out of range: -1

Parameters:
    beginIndex - the beginning index, inclusive.
    endIndex - the ending index, exclusive.

StringIndexOutOfBoundsException の原因:

指定されたコード スニペットでsubstringは、文字列の全長を超える文字列をフェッチしようとしていますendIndex(i+j文字列の全長を超えます):

str = word.substring(i, i + j);

単語「ラム」の i=2 および j=2 の場合を考えてみましょう。

それならstr=word.substring(2, 4); 無理だろう

質問で与えられたコード スニペットに似たソリューション:

これで問題は解決するはずです:

 public String getSubstrings()
    {
        String str="",substr = "";
        for (int i = 0; i < word.length(); i++) {
            for (int j = 0; i+j <= word.length(); j++) { //added i+j and equal to comparison
               substr = word.substring(j, i + j); //changed word.substring(i, i + j) to word.substring(j, i + j)
               if("".equals(substr))continue; //removing empty substrings
               str += substr; //added concatenation + operation
               str += "\n";
            }
        }
        return str+word;
    }

テストケース:

の場合word="rum"、次の出力が得られます。

r
u
m
ru
um
rum
于 2013-07-03T16:38:20.987 に答える
4

あなたのロジックは複雑なようで、例外の原因です:

str = word.substring(i, i + j);

iあなたとj両方が等しいと考えるとword.length()-1substring()失敗します。

あなたは簡単に行うことができます:

public String getSubstrings(String word){
   StringBuilder sub= new StringBuilder();
   for( int i = 0 ; i < word.length() ; i++ )
   {
      for( int j = 1 ; j <= word.length() - i ; j++ )
      {
         sub .append(word.substring(i, i+j)).append("\n");
      }
   }
   return sub.toString();
}

注:で多くの連結を行う場合は、StringBuilder代わりにを使用することを検討してください。StringString

于 2013-07-03T16:41:41.913 に答える
1

私はこのパーティーに少し遅れており、私自身は非常に新しいプログラマーですが、昨夜、同様のメソッドを作成しようとしているときに同じエラーに遭遇していました。

私にとっては、ネストされたforループのカウンター変数の名前を、それらが追跡しているものを説明する名前に変更するのに役立ちました. 外側のループには を使用int subLengthし、内側のループにはint position(開始位置) を使用しました。これを行う他の方法があると確信していますが、私は自分の解決策に満足していました. この質問を調べている他の誰かに役立つことを願っている疑似コードを次に示します。

     for each possible substring length 1 up to and including the original word length: 
            generate substrings starting at the 0th position, and then starting at each 
            proceeding letter up to but not including (word.length() - (subLength - 1))
于 2015-07-17T18:58:42.710 に答える