C++はKMPアルゴリズムとその最適化を実現する

1249 ワード

自分で簡潔なバージョンを書いて、注釈をつけました.
 
最初の関数は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;

}