C++はKMPアルゴリズムとその最適化を実現する
1249 ワード
自分で簡潔なバージョンを書いて、注釈をつけました.
最初の関数はKMPのnext配列を得ることである.
next配列の本質:2つの文字列が一致しない場合、T列は現在のインデックスのnext値に基づいてT列の対応する位置にジャンプすることができる.
1、nextの最初の値を-1に設定します.
2、残りのT列を巡る
3、T列前後比較、等しい場合はnextで対応位置に1を加算
4、等しくなければ、T列中の等価位置を遡る
2つ目はKMP関数です
1、まずnext配列を生成する
2、S列、T列を遍歴する
3、等しいときは前へ進む
4、不等時かつその時に対応するnext値が-1の場合は、その時のT列を代表してまた第1の位置に戻り、S列、T列の該当箇所が一致しない
5、その他の場合はnext値をT列の移動変数jに与える
6、nextを解放する
7、jがT列の末尾に到達した場合、S列、T列が各所一致したことを示し、i-jを返す
いいえ、一致に失敗しました.-1を返します.
最初の関数はKMPのnext配列を得ることである.
next配列の本質:2つの文字列が一致しない場合、T列は現在のインデックスのnext値に基づいてT列の対応する位置にジャンプすることができる.
1、nextの最初の値を-1に設定します.
2、残りのT列を巡る
3、T列前後比較、等しい場合はnextで対応位置に1を加算
4、等しくなければ、T列中の等価位置を遡る
void getNext(string &T,int *next)
{
int i = 0, j = -1;
next[0] = -1;
while (i < T.size() -1)
{
if (j == -1|| T[i] == T[j])
{
i++;
j++;
if (T[i] != T[j])
next[i] = j;
// , T aaaab , , ,
else
next[i] = next[j];
}
else
j = next[j];
}
}
2つ目はKMP関数です
1、まずnext配列を生成する
2、S列、T列を遍歴する
3、等しいときは前へ進む
4、不等時かつその時に対応するnext値が-1の場合は、その時のT列を代表してまた第1の位置に戻り、S列、T列の該当箇所が一致しない
5、その他の場合はnext値をT列の移動変数jに与える
6、nextを解放する
7、jがT列の末尾に到達した場合、S列、T列が各所一致したことを示し、i-jを返す
いいえ、一致に失敗しました.-1を返します.
int KMP_method(string &S, string &T)//S ,T
{
int *next = new int[T.size()];
getNext(T, next);
int i = 0, j = 0;
while (i < S.size() && j < T.size())
{
if (S[i] == T[j])
{
i++;
j++;
}
else if (next[j] == -1)
i++;
else
j = next[j];
}
if (next)
{
delete[]next;
next = NULL;
}
return (j == T.size()) ? i -j : -1;
}