2017-09-27 10 views
2

私の目標は、指定されたパターンが配列リストに追加された後の文字を取得することです。私の問題は、このコードでは私はエラーが発生することです。テキストの長さを超えています。文字のarraylistに文字列中のパターンが出現するたびに文字を追加したい

public static ArrayList<Character> getCharsThatFollowPattern (String text, String pattern) 
    { 
    ArrayList<Character> charAfterPattern = new ArrayList<Character>(); 
    int patternLength = pattern.length(); 
    int i = 0; 
    while (i < text.length()) 
    { 
     charAfterPattern.add(text.charAt(text.indexOf(pattern, i) + patternLength)); 
     i = i + text.indexOf(pattern, i) + patternLength; 
    } 
    return charAfterPattern; 
} 
+1

エラーは何ですか?ところで、デバッガでコードをステップ実行すれば、おそらく自分自身を理解するでしょう。 – dave

+2

あなたは実際に何をしようとしていますか?単純な 'String'(または最悪の場合、' StringBuilder')が基本的に同じことをするとき、 'ArrayList 'を扱うことは非常に普通です。 – Bohemian

+0

私はIndexOutOfBoundsExceptionを取得します。文字列インデックスが範囲外です:7 –

答えて

0

コードには3つの大きな問題があります。

最初の2つは、indexOf()が動作する方法に関連しています。

  • パターンが見つからない場合は-1を返します。この場合は許可せず、したがって文字列の一部を2回処理します。
  • 文字列の開始を基準にしたインデックスを返します。開始以外の場所から検索した場合でも、したがって、i = i + text.indexOf(...ではなく、i = text.indexOf(...とする必要があります。

第3の問題は、パターンがテキストの最後にある場合を適切に処理しないことです。次の文字はありません。

ここであなたに基づいて私のラフなソリューションです:

public static List<Character> getCharsThatFollowPattern (String text, String pattern) 
{ 
    List<Character> charAfterPattern = new ArrayList<Character>(); 
    int patternLength = pattern.length(); 
    int i = 0; 
    while (i < text.length()) 
    { 
     int index; 
     if ((index = text.indexOf(pattern, i)) < 0) // Check pattern is present 
      break; 
     i = index + patternLength; 
     if (i < text.length()) // Check there is a next character 
     { 
      charAfterPattern.add(text.charAt(i)); 
     } 
    } 
    return charAfterPattern; 
} 

基本テスト:

("abc", "ab")  => [ 'c' ] 
("abcabdabe", "ab") => [ 'c', 'd', 'e' ] 
("abcabdab", "ab") => [ 'c', 'd' ] 
("ababdab", "ab") => [ 'a', 'd' ] 
0

ここStringのより適切な戻り値の型を使用して、簡単な解決策があります:

public static String getCharsThatFollowPattern(String text, String pattern) { 
    return text.replaceAll(".*?" + pattern + "(.)(.(?!" + pattern + "))*", "$1"); 
} 

場合には、あなたは必死に、絶対にList<Character>を持っている必要があります、タイプで:あなたは常にList<Character>ないArrayList<Character>つまり、メソッドAPIの最も抽象型を使用する必要があること

public static List<Character> getCharsThatFollowPattern(String text, String pattern) { 
    return text.replaceAll(".*?" + pattern + "(.)(.(?!" + pattern + "))*", "$1") 
     .chars().mapToObj(i -> (char) i).collect(Collectors.toList()); 
} 

も注意してください。 Liskov substitution principleを参照してください。

+0

あなたのメソッドと私のオリジナルの例の両方で、 ['b'、 'b']の代わりに[b ']を使用します。それは学校用ですので、ArrayListにする必要があります –

+0

私の元の例は残念です。私が渡す必要があるテストは "abababa"、 "aba"で、それは['b'、 'b']を返します –

+0

@evan [[b]]を返すべきですか?言い換えれば、マッチングの際に*入力を再利用する必要がありますか? – Bohemian

関連する問題