KMP
怎么求KMP
border是KMP中的关键概念,border就是一个字符串,它既是某个串的前缀,又是后缀。
定义 \(nxt_i\) 是对于前 \(i\) 个字符串的最长border,在前缀相同部分的末尾位置。
\(nxt_i\) 的作用是,如果在 \(a_{i+1}\) 失配,作为模板串不会从头开始匹配,而是从 \(nxt_i\) 开始匹配。因为前后缀是相同的,因为前后缀是相同的,文本串中对应 \(1 \sim nxt_i\) 的位置肯定匹配成功了。
假设 \(b\) 是模板串,\(a\) 是文本串,求有多少个匹配:
int j=0;
for(int i=1;i<=lena;i++){
while(b[j+1]!=a[i]&&j!=0)j=nxt[j];
if(b[j+1]==a[i])j++;
if(j==lenb){
v.push_back(i-lenb+1);
}
}
求 \(nxt_i\) 是给一个指针 \(j\) ,用模板串自己的前缀匹配后缀。
int j=0;
for(int i=2;i<=lenb;i++){
while(b[j+1]!=b[i]&&j!=0)j=nxt[j];
if(b[j+1]==b[i])j++;
nxt[i]=j;
}
画图,发现文本串指针增加 \(lena\) 次,模板串匹配时最多向前 \(lenb\) 次,时间复杂度 \(O(lena+lenb)\) 。
KMP求最小循环节
画图。最小循环节是 \(n-nxt_n\) 。

浙公网安备 33010602011771号