KMP算法
大意
大串a中找小串b
小串处理
(next[i])表示(b[i])匹配过程中失配情况下可以向前跳几个字符,意思就是b的前i个的公共前后缀的最大长度
如(B="ABCBCABCD",i=7)时(next[i])为(3)。
处理:如果(b[next[x-1]]==b[x]),则(next[x]=next[x-1]+1),否则在(x-1)的公共前后缀中找,迭代这一过程
(query(x,y)={^{ next[x-1]+1 (b[next[x-1]]==y)}_{ query(next[x-1],y) (b[next[x-1]]!=y)})
(next[i]=query(i,b[i]))
可以用(while)实现
大串处理
若现在找到大串的(p1)位置与小串的(p2)位置而失配,那么接下来找(b[next[p2]+1])是否等于a[p1],如果依然不等于,就在next[p2]+1里面继续找
相当于每次讲(p2)迭代为(next[p2])
代码
#include<bits/stdc++.h>
using namespace std;
int next[1000010];
char a[1000010],b[1000010];
int lena,lenb;
int p1,p2;
int main(){
cin>>a+1>>b+1;
lena=strlen(a+1);
lenb=strlen(b+1);
for(int i=2;i<=lenb;i++){
while(p2&&b[i]!=b[p2+1]){
p2=next[p2];
}
if(b[p2+1]==b[i]){
p2++;
}
next[i]=p2;
}
p2=0;
while(p1<=lena){
while(p2>0&&b[p2+1]!=a[p1]){
p2=next[p2];
}
p2+=b[p2+1]==a[p1];
p1++;
if(p2==lenb){
cout<<p1-lenb<<'
';
p2=next[p2];
}
}
for(int i=1;i<=lenb;i++){
cout<<next[i]<<' ';
}
return 0;
}