0

私は現在、文字の配列として表す必要があるテキスト行を表す TextLine クラスを作成するクラスのプロジェクトに取り組んでいます。文字列クラスを間接的または直接的に使用して TextLine オブジェクトを表現することは許可されていませんが、それを使用してパラメーターを操作することはできます。

メソッドの 1 つは、TextLine オブジェクトのフラグメントでもあるパラメーターの引数として文字列を受け取り、この TextLine でフラグメントが最初に出現したインデックス位置を返すことになっています。フラグメントが見つからない場合は 1。

今、私は indexOf メソッドを理解しようとしていますが、私の問題は、私のメソッドが開始点を一度しかチェックしないことです。そのため、TextLine オブジェクトの文字が最初はフラグメントの文字と一致せず、オブジェクト内の別の場所で別の一致がある場合、メソッドはその開始点をチェックしません。

たとえば、テキストラインとして penplay を入力し、フラグメントとして play を入力するとします。明らかに、TextLine で再生が発生していますが、私の indexOf メソッドが行うことは、インデックス 0 で penplay からの最初の p をチェックし、その後の文字が再生の長さに一致するかどうかを引き続き確認することです。そうでない場合は、-1 を返します。アルゴリズムが別の開始点を検索し続けるようにする方法はありますか?

これは私のコードにあるものです:

public int indexOf(String fragment){

char[] temp = fragment.toCharArray();

int j = 0;
for(int i = 0; i < someText.length; i++){
    while(someText[i] == temp[j]){

        for(j = 1; j < temp.length; j++){
            if(temp[j] != someText[i+j]){
                return -1;
            }
        }

        return i;

    }
}

return -1;

}
4

3 に答える 3

4

必要がないときに、最初の文字を特別にケース化しています。基本的にあなたは言う必要があります:

  • 潜在的な開始文字ごとに...
    • その候補位置から全体がfragment一致するか?

次のようなものです:

// Only deal with *viable* starting points
for (int i = 0; i < someText.length - temp.length; i++) {
    boolean found = true;
    for (int j = 0; j < temp.length && found; j++) {
        if (temp[j] != someText[i + j]) {
            found = false;
        }
    }
    if (found) {
        return i;
    }
}
return -1;

これは、内側のループを抽出することでリファクタリングできます。

for (int i = 0; i < someText.length - temp.length; i++) {
    if (textMatches(temp, i)) {
        return i;
    }
}
return -1;

...
// TODO: Javadoc to explain parameters :)
private boolean textMatches(char[] chars, int startingIndex) {
    for (int i = 0; i < chars.length; i++) {
        if (chars[i] != someText[i + startingIndex]) {
            return false;
        }
    }
    return true;
}
于 2011-07-13T22:01:00.050 に答える
1

doesStringExistAtIndex(j, fragment)その設定方法は、一種の機能として適しているようです。文字列が最初のインデックスに存在しない場合は -1 を返すため、次のようにすることができます。

//assuming that "this" is the subject that you are searching in
public int indexOf(String fragment){
  for(int i=0; i<this.length; ++i){
    if(doesStringExistAtIndex(i, fragment))
      return i;
  }
  return -1;
}
于 2011-07-13T22:02:11.280 に答える
0

これがあなたの望むものかどうかはわかりませんが、基本的には indexOf メソッドを作成しました。私はいくつかのテストを行いましたが、私が行ったいくつかのテストでは問題なく動作するように見えました. もちろん、テストを簡単にしたかったので見た目は異なりますが、使用する場合は 30 秒以内に変換する必要があります。

public int indexOf(String fragment, String source)
{
    char[] temp = fragment.toCharArray();
    char[] someText = source.toCharArray();

    outer : for(int i = 0; i <= someText.length - temp.length;i++) //stops looping because why loop after the fragment is longer than the source we have left when its impossible to find
    {
        if(someText[i] == temp[0]) //if the first characters are the same
        {
            int q = 0;
            while(q < temp.length) //loop through the fragment
            {
                if(someText[i+q] != temp[q]) //if the characters are not the same, stop, and go to the next character of the source. Don't return anything
                {
                    continue outer; //continues the loop labeled 'outer' (e.g. outer : for(...) )
                }
                q++; //increment index since they both match
            }
            return i; //fragment and some part of the source matched since it reached here. Return the index of the first character
        }
    }
    return -1; //reached here because nothing was found :( return -1
}

EDIT 0行コメントを追加

于 2011-07-13T22:19:19.737 に答える