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);
}