I.はじめに
KMPアルゴリズムは、テキスト文字列、アルゴリズムに/位置含まれているテンプレートの数を見つけるパターン文字列からテキスト文字列です。
例えば、abcabcccabcテキスト文字列に、テンプレートの文字列abc数は、3である0,3,8その開始位置です。
第二に、アイデア
暴力は、ループO(N-ための2つであり、見かけ上欠如研磨を取得するM)とKMPはO(N + M)です。
KMPは正直言って、少し周りが、実際のキーポイント:同じ接尾辞接頭辞を持つ最長の文字列のテンプレートを見つけ、次のストレージアレイによって。
どのように理解するには?栗のため
abcabテンプレート文字列のため、我々はゼロから次のアレイ構造を開始します
文字列 | 接頭辞 | サフィックス | 最長共通接尾辞 | 次のアレイ |
---|---|---|---|---|
"A" | [] | [] | ノー | 次の[0] = 0 |
"AB" | [A] | [B] | ノー | 次の[1] = 0 |
"ABC" | [AB] | [C、BC] | ノー | 次の[2] = 0 |
"ABCA" | 【、AB、ABC] | [A、C、CBS] | A | 次の[3] = 1 |
"abcab" | 【、AB、ABC、ABCA] | [B、AB、タクシー、bcab] | から | 次の[4] = 2 |
"ABCABC" | 【、AB、ABC、ABCA、abcab] | [C、BC、ABC、CABC、bcabc] | ABC | 次の[5] = 3 |
abcabbテキスト文字列、5マッチング、即ちabcabためのBは、文字列照合テンプレートがabcabするC、文字の位置に、この時間差を
力アルゴリズムは、テキスト文字列の位置、すなわちBをバックジャンプしなければならない場合、およびテンプレート配列バック初期位置、再マッチングにジャンプしなければならない
次KMPアルゴリズムを使用して、テンプレート文字列[-1 =現在位置4] = 2、即ち、第二の位置、ABCケースのテンプレート文字列にジャンプし、テキスト文字列でありますABCABBは、それを見つけますか?テンプレートの接頭文字列AB& Cと接尾辞テキスト文字列AB& AB&ので、テンプレート配列を元に戻す必要はありません同じ接頭辞を持つB、比較が継続すること、すなわち、テキスト文字列は大文字でありますABCAB、および文字列ABのテンプレートは、その後、次の文字を比較します。
第三に、コード
int nextt[maxn];
void get_nextt(char pattern[]){//为pattern字符串创建nextt数组
nextt[0] = 0;
int max_length = 0;
for(int i = 1;pattern[i];i++){
while(max_length > 0 && pattern[max_length] != pattern[i])
max_length = nextt[max_length-1];
if(pattern[i] == pattern[max_length])
max_length++;
nextt[i] = max_length;
}
}
queue<int> search(char text[],char pattern[]){//从test字符串中,寻找含有多少个pattern字符串,并将其开头位置存入队列中
queue<int> q;
int pattern_length = strlen(pattern);
get_nextt(pattern);
int count = 0;
for(int i = 0;text[i];i++){
while(count > 0 && pattern[count] != text[i])
count = nextt[count-1];
if(pattern[count] == text[i])
count++;
if(count == pattern_length){
q.push(i-pattern_length+1 );
count = nextt[count-1];
}
}
return q;
}