私はこの質問に答えるのに少し遅れていますZ-Algorithmが、対応するものよりもはるかに速いと思います。最悪の場合の複雑さはO(m + n)であり、パターン/テキストの前処理を必要としません。他のアルゴリズムと比較して、コーディングも非常に簡単です。
次のように機能します。
たとえば、文字列がありますS ='abaaba'。のz(i)値を見つけますi=0 to len(S)-1。説明に入る前に、最初にいくつかの定義を置いておきます。
z(i)=いいえ。のプレフィックスの文字のうち、のプレフィックスSと一致するものs(i)。
s(i)=のith接尾辞S。
以下はのs(i)値ですs = 'abaaba'。
s(0) = 'abaaba' = S
s(1) = 'baaba'
s(2) = 'aaba'
s(3) = 'aba'
s(4) = 'ba'
s(5) = 'a'
z値はそれぞれ
z(0) = 6 = length(S)
z(1) = 0
z(2) = 1
z(3) = 3
z(4) = 0
z(5) = 1
アルゴリズムの詳細については、次のリンクを参照してください。
http://codeforces.com/blog/entry/3107
https://www.youtube.com/watch?v=MFK0WYeVEag
今、すべてを見つけるにはO(N)が必要です z、前処理のオーバーヘッドなしで値です。このロジックを使用して特定の文字列のパターンをどのように一致させることができるのでしょうか?
例を見てみましょう。パターン(P):abaテキスト(T): aacbabcabaad。
これをP $ Tの形式で入力します。($-パターンまたはテキストのどちらにも表示されない文字。$しばらくして重要性が出てきます。)
P$T = aba$aacbabcabaad
知ってる len(P) = 3。
のすべてのz値P$Tは
z(0) = 16 = len(P$T)
z(1) = 0
z(2) = 1
z(3) = 0
z(4) = 1
z(5) = 1
z(6) = 0
z(7) = 0
z(8) = 2
z(9) = 0
z(10) = 0
z(11) = 3
z(12) = 0
z(13) = 1
Z(14) = 1
Z(15) = 0
さて、これはz(i)= len(P)です。Ans = 11.したがって、パターンはAns-len(P)-1=に存在し7ます。-1のためです$キャラクターです。
さて、なぜか$そのような特殊文字が重要です。考えてみましょうP = 'aaa'とT = 'aaaaaaa'。特殊文字がないz(i)と、すべてに増分値があります。以下の式を使用して、テキスト内のパターンの位置を見つけることができます。
条件:z(i)> = len(P)および位置:Ans-len(P)。ただし、この場合の状態は少し複雑でわかりにくいものになります。私は個人的に特殊なキャラクターのテクニックを使うことを好みます。