文字列マッチングの基礎(下):BMアルゴリズムは簡単KMPアルゴリズムを使用する方法を理解できますか?
KMPアルゴリズムの理論的根拠
主は、列Aであると仮定し、文字列パターンはbがある、と呼ばれる不正な文字を一致させることができない文字は、一致は、文字列の接頭辞の一部を行うために呼ばれてきました
不正な文字、パターン文字列のバックスライド、プロセスにおけるスライド限り、パターン文字列上下と良いプレフィックス一致を持っているに直面したとき、比較は文字列の最初の数文字を接尾サブストリングパターンのプレフィックスがグラブに相当します比較プレフィックスストリングで
KMPアルゴリズムは、文字列と文字列マッチング処理のメインモードである悪いキャラクターに直面したとき、接頭辞のより良い位置合わせのために、法律、ワンタイムスライディングモード文字列ビットの多くを見つけることかてきました。
グラブプレフィックスサブプレフィックスと良好であることができる最長の文字列一致を見つけ、そのサフィックスストリングで、それ自体を付けることは、接頭語の最も長い部分は、サブストリングは、{V}、kの長さで一致させることができることが想定されますワンタイムパターン文字列は、私はそのままバックJKビット、不正な文字に相当するたびに、更新されたjのkを、スライドさせ、その後、比較を続けます
プレフィックス良いはすべてのサフィックスは、最長の部分文字列の一致かもしれ接頭サブ接尾最長一致接頭サブと呼ばれることも最長の部分文字列と呼ばれるプレフィックス部分文字列を、対応するサブストリングサフィックスと一致していること
KMPアルゴリズムは、先にパターン文字列を格納するアレイを構築する最長一致接頭サブストリング、また、故障関数と呼ばれる配列インデックス当たりのアレイの横配列として定義された各プレフィックス文字インデックスの終わりであってもよいです接頭辞インデックス値は、添え字の最後に文字の最長一致接頭部ストリングとすることができる配列の最後の接頭辞であります
パターン文字列:ababacd
パターン文字列のプレフィックス(接頭辞良い候補)端文字添字プレフィックスは添字の次の値の末尾に最長一致接頭文字サブストリングであってもよいです
0 -1(不在)次の[0] = -1
AB 1 -1次の[1] = -1
次ABA 2 0 [2] = 0
ABAB 3 1次の[3] = 1
アベバ4 2次の[4] = 2
ababac 5 -1次の[5] = -1
たとえば、接頭辞候補:ABA
文字の文字列を終了サブインデックスすることができ、最長プレフィックス一致を見つけるABAしてみましょう
abaaba
AA
BAAB //終わり、BA!= AB、の最初の行のみが、添字0、次を= [2] = 0
KMPアルゴリズムのフレームワーク:
//a,b分别是主串和模式串;n ,m 分别是主串和模式串的长度
public static int kmp(char[] a ,int n,char[] b ,int m ){
int[] next = getNexts(b,m);
int j = 0 ;
for(int i = 0 ; i < n ; ++i){
while(j > 0 && a[i] != b[j]){ //一直找到a[i]和b[j]
j = next[j - 1] + 1;
}
if(a[i] == b[j]){
++j;
}
if(j == m){ //找到匹配模式串的了
return i - m +1;
}
}
return -1;
}
演算機能障害
どのように次のアレイを数えますか?
大きな値に添字小よれば、順次、我々は次の[I]、次の前に[0]、次の[1]、...、次の[I-1]がアウトであると考えられる場合を計算する次の配列を、計算します次の値によって次の[i]は、それ素早く派生値をすることができ、計算されましたか?
次の[I-1] = K -1、すなわち、bはサブストリング[0、K-1]はBである場合は[0、K-1] B場合は[0、I-1]は、最長一致接頭サブストリングであります次の文字B B [0、k]をサブストリングがBであること[i]は次の文字Bの[K]、およびb [0、I-1]マッチ[0、i]は、最長マッチングサブすることができ文字列、次の[I] = K
// b 表示模式串,m表示模式串的长度
private static int[] getNexts(char[] b ,int m){
int[] next = new int[m];
next[0] = -1;
int k = -1;
for(int i = 1 ; i < m ; ++i){
while(k != -1 && b[k+1] != b[i]){
k = next[k];
}
if(b[k + 1] == b[i]){
++k;
}
next[i] = k ;
}
return next;
}
推奨: