KMPアルゴリズムは、最初に少し複雑に見えますが、原則は考えて明確に理解するために、非常に簡単です。
ここでは簡単な栗は以下のとおりです。
主な文字列s:abcabfd
パターン文字列トン:abcabe
原始的な方法、文字がメインの文字列を比較することによって実行される場合、I = 5、S [5] = Fの位置と、そのJ = 5、T [5] = E一致しない、のみ見出さします= I = 2、そして試合jから再び始めます。
パターン文字列の特性に起因して、実際には、:AB& C AB& E二AB&文字列を、あるフロントはまた、我々は直接F及びJ = 3、T [3]ができ、メインストリングAB&Fを有している Cを= ため対照的に、ABの前部は、一度比較以下で同じではないからです。
そう実際KMPアルゴリズムは、パターン文字列の特性を利用した文字列が、より大きなパターンの繰り返しがある場合、私は移動していない少なくともメインストリームではなく、アルゴリズムをバックトラックとして原画像であるため、決意は、多くの省略されてもよいです。
KMPアルゴリズムは2つの部分に分かれています。
本体1)の.KMP
2).nextアレイ
1)二つの文字列の効果は、パターンマッチングであるが、1))次の配列2を使用する必要があり、マッチングを行う前に次のアレイを構築することが第一。
それはSと判断された次の配列栗、上に上記と同様の効果[5] Tと等しくない[5]、ダイレクトルックアップ次の[5]、次の[5] fが向けられるべきは、ここでは、比較的文字であります[2]が互いに直接比較することができるTからなる次の[5] = 2、F AB ABとしてEに等しい前に、知られています。
建物の次の配列:
パターン文字列tを考えてみましょう、iとjのパターン文字列の位置:
T [i]は=さt [j]は、それが既知である場合に(1〜I)は、次の[J + 1]、即ちメインストリングがないストリングモデルの、(J-I + 1〜j)の間の正確に等しいです等しいJ + 1つの文字で、比較は次の[J + 1] = I + 1で次のI番目の要素でなければなりません。
Tもし[I]!= T [j]が、しかし正確に等しく、その後、j番目の要素の間(1〜I-1)及び(J-I + 1〜jを-1)ことが見出され、べき第一及び第二次に[J再び】コントラスト要素、このときもし等しい、次の[J + 1] =次の[J] +1。
そうでない場合は、第一次の[次[J]の元素であり、次のいずれかを検索し続けます。
次の配列を取得した後、残りのKMP体は、非常に単純であれば、iとjは、コントラストを対応する要素、などもしS [I] == S [j]を、私は++、J ++を、そうでない場合、次のIと[J]要素は、コントラスト......
コード:
コードは、2つの部分に分けることができます。
次の別の部分の配列を作成するために、本体のKMP部分。
また、それほどのアレイの次の部分を作成します。
彼らの役割は、以下のとおりです。
AAB次のようなパターン文字列
次の作成する場合、次の[0] -1性質等しく、そして次に[1]、この部分なしで、すなわちメインストリング場合、0に設定され、文字列パターン部は、また、I = 1に等しくありません実際に、T [0]これに対し移動、T [0]、T [1]であり、従ってそれは、-1に直接提供されなければならない必要はありません。
(!T [i]を= T [J])であれば 、次の[i]を= J; 他に 次の[i]を=次の[J]。
クラスソリューション { パブリック: INT KMP(文字列s、文字列T) { ベクトル<整数>次= GET_NEXT(T)。 int型私= 0; int型J = 0; (私はs.size()&& J <t.size()<)しながら { IF(jは== - 1 || S [I] == S [J]) { I ++。 J ++; } そう J =次の[J]。 } IF(J <t.size()) 戻り0; 他の リターン私は、 } ベクトル<整数> GET_NEXT(文字列T) { ベクトル<整数>次の(t.size() - 1)。 int型私= 0; int型J = -1; - (1)私は(t.size()<)しながら { IF(J == - 1 || T [I] == T [J]) { I ++と、 J ++; (!T [i]を= T [J])であれば 、次の[i]を= J; 他に 次の[i]を=次の[J]。 } そう J =次の[J]。 } 次返します。 } }。