最近在看字符串模式匹配KMP算法,不涉及优化,非小白科普帖.
KMP算法的关键:
1.求模式串next数组
2.计算后移步数
3.字符串比较
难度依次降低.
求模式串next数组建议看下https://www.zhihu.com/question/21474082.这里对文中图2进行一下修改,并解释下代码中的k=next[k].
接原文,图中前两行表示next[q]=k,模式串前q个字符中,前子串和后子串相同的最长长度是k.
现在要求next[q+1],但P[q]≠ P[k].
假设模式串前q+1个字符中,前子串和后子串相同的最长长度是j.那么j肯定小于k,而且P[j]==P[q].
最关键的是因为P[j-1]==P[q-1],所以P[j-1]==P[k-1].
从图中二三行看,三行的P[0]....P[j-1]与二行的P[0]....P[k-1]后部分完全相同.
套用next数组的定义,可以把P[0]....P[j-1]当作P[0]....P[k-1]的前缀,与它的后缀完全相同.
则next[q+1]=j=next[k]+1.(也就是代码中next[++i] = ++k;)
附next数组代码.
void initNextArray(string p){
int k = -1;
int i = 0;
next[0] = -1;
while(i < p.size()-1){
if(k == -1 || p[k] == p[i])
next[++i] = ++k;
else
k = next[k];
}
}