KMP
原理看这:原理orz
模板:
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 1e6 + 10;
int ne[N];
int lt,lp;
char a[N],b[N];
void getnext(){
int j = 0,k = -1;
ne[0] = -1;
while(j < lp){
if(k == -1 || b[j] == b[k]){
ne[++ j] = ++k;
}
else k = ne[k];
}
}
void KMP(){
int i = 0,j = 0;
while(i < lt){
if(j == -1 || a[i] == b[j]) i ++,j ++;
else j = ne[j];
if(j == lp){
printf("%d\n",i - lp + 1);
j = ne[j];
}
}
}
int main(){
scanf("%s",a);
scanf("%s",b);
lt = strlen(a),lp = strlen(b);
getnext();
KMP();
for(int i = 1;i <= lp;i ++){
printf("%d ",ne[i]);
}
return 0;
}
扩展KMP
原理:原理orz
模板:
int nxt[N],ext[N];
int slen,tlen;
char s[N],t[N];
void getnext(){
nxt[0] = tlen;
int now = 0;
while(t[now] == t[now + 1] && now + 1 < tlen) now ++;
nxt[1] = now;
int p0 = 1;
for(int i = 2;i < tlen;i ++){
if(i + nxt[i - p0] < nxt[p0] + p0) nxt[i] = nxt[i - p0];
else{
int now = nxt[p0] + p0 - i;
now = max(0,now);
while(t[now] == t[i + now] && i + now < tlen) now ++;
nxt[i] = now;
p0 = i;
}
}
}
void exkmp(){
getnext();
int now = 0;
while(s[now] == t[now] && now < min(slen,tlen)) now ++;
ext[0] = now;
int p0 = 0;
for(int i = 1;i < slen;i ++){
if(i + nxt[i - p0] < ext[p0] + p0) ext[i] = nxt[i - p0];
else{
int now = ext[p0] + p0 - i;
now = max(now,0);
while(t[now] == s[i + now] && now < tlen && now + i < slen) now ++;
ext[i] = now;
p0 = i;
}
}
}