KMP

给定两个字符串\(s1\)\(s2\),求\(s2\)\(s1\)中所有的出现位置。

\(KMP\)有递推的感觉。

在模式串\(str2\)中,对于每一位\(str2(i)\) ,它的\(kmp\)数组应当是记录一个位置\(j\),\(j \leqslant i\),并且满足\(str2(i)=str2(j)\),并且在\(j!=1\)时理应满足\(str2(1)\)\(str2(j-1)\)分别与\(str2(i-j+1)\)\(str2(i-1)\)按位相等。

每次位置指针\(i++\)时,失配指针\(j\)至多增加一次,所以\(j\)至多增加\(len\)次,从而至多减少\(len\)次,所以就是 \(O(len_N+len_M)=O(n+m)\)的复杂度。

最小循环节(将这个循环节无限赋值后能表达出这个串)长度为\(n-nxt[n]\)

\(code\)

for(int i=2;i<=m;++i)
{
    while(pos&&t[i]!=t[pos+1]) pos=nxt[pos];
    if(t[i]==t[pos+1]) pos++;
    nxt[i]=pos;
}
pos=0;
for(int i=1;i<=n;++i)
{
    while(pos&&s[i]!=t[pos+1]) pos=nxt[pos];
    if(s[i]==t[pos+1]) pos++;
    if(pos==m) printf("%d\n",i-m+1);
}
posted @ 2020-01-22 19:57  lhm_liu  阅读(137)  评论(0编辑  收藏  举报