KMPの理解について書く、我々は二つの文字列AとB、Aを持っている、B BEGは何度も登場しました。
この問題は、KMPを使用して解決することができます。
最悪の場合、単純なO(N ^ 2)Aと一致します。KMPは非常に効率的なアルゴリズムの効率は、O(N)Aです。
我々は、このように大幅に効率を向上させる、KMPアルゴリズムは、最初の文字列であり、Bは、時間的に前KMP(次)配列のミスマッチリバウンドのうち、自分自身にマッチすると思いました。
KMPは、[1]のように-1に定義されます。最初であることは、それを使用しています。
1つ の#pragma GCC最適化(2) 2の#include <ビット/ STDC ++ H> 3 使用して 名前空間STDを、 4 のconst int型 MAXN = 1E5 + 5 。 5 CHAR [MAXN]、B [MAXN]。 6 INTのKMP [MAXN]。 7 INT )(メイン 8 { 9 のscanf(" %sの%sの"、+ 1、B + 1 )。 10 INT ALENの=のSTRLEN(A + 1 )。 11 INT BLEN = STRLEN(B + 1 )。 12 用(int型 I = 2、J = 0 ; I <= BLEN ++ I) 13 { 14 ながら(Jの&&のB [I] = B [J +!1 ])J = KMP [J]。 15 もし(B [I] == B [J + 1 ])J ++ 。 16 KMP [I] = J。 17 } 18 INT ANS = 0 。 19 のために(int型 I = 1、J = 0 ; iが= ALENを<; ++ i)が 20 { 21 ながら(!J && [I] = B [J + 1 ])J =KMP [J]。 22 であれば([I] == B [J + 1 ])J ++ 。 23 もし(J == BLEN)ANS ++ ; 24 } 25 KMPの[ 1 ] = - 1 。 26 のためには、(int型 I = 1 ; I <= BLEN; ++ I)のprintf(" %dの" 、KMP [I])。 27 のprintf(" \ nの%d個の\ n " 、ANS)。 28 リターン 0 ; 29 }
いくつかの例を与えます
羅区P3375
hdu1686
hdu1711
hdu2087