KMP 算法
KMP (Knuth-Morris-Pratt) 算法是一种在线性时间内匹配文本串和模式串的算法.
称字符串的 Border 集合为
[operatorname {Border} (S) = {Pre_S(j) | Pre_S(j) = Suf_S(n - j + 1) land j
ot= n }
]
称字符串 (S) 的最长 Border 为 (fail(S)), 或者 (next(S)). 容易发现递归枚举 (fail(S), fail(fail(S)), dotsc) 可以得到 (S) 的 (operatorname {Border}) 集合.
把每个位置 (p) 连向 (fail(p)) (包括 (0) 号节点), 可以得到一棵以 (0) 号节点为根的树, 称为 Border tree.
KMP 算法可以在线性时间内得到字符串 (S) 每个前缀的 (fail) 函数, 并可以利用它进行字符串的匹配.
求 Border 和匹配
int n,m;
char s1[nsz],s2[nsz];
int nxt[nsz];
void getnext(char *s,int n){
int l=0; //l means the length of prefix matched
nxt[1]=0;
rep(i,2,n){
while(l&&s[l+1]!=s[i])l=nxt[l];
if(s[l+1]==s[i])++l;
nxt[i]=l;
}
}
int pl[nsz],pp=0;
void match(){ //s2->s1
pp=0;
int l=0; // the length of prefix of m matched
rep(i,1,m){
while(l&&s2[l+1]!=s1[i])l=nxt[l];
if(s2[l+1]==s1[i])++l;
if(l==n){pl[++pp]=i-l+1;l=nxt[l];}
}
}