KMP算法
next数组
对于一个字符串,next[i]=k表示当前位置前面有k个字符(不包括全前缀)和开头k个字符一样,或者若当前位置匹配失败应该返回的下标处.kmp算法核心就是怎么求一个字符串的next数组.
模板
1 char s[MAX]; 2 int next[MAX]; 3 4 void kmp(int cnt) 5 { 6 int i=0,k=-1; 7 next[0]=-1; 8 while(i<cnt) 9 { 10 if(k==-1||s[i]==s[k]) next[++i]=++k; 11 else k=next[k]; 12 } 13 return ; 14 }
这里cnt是字符串长度,刚开始设next[0]=-1是为了标记字符串开头,当第k个字符和第i个字符一样时,第next[i+1]=k+1,因为这时候开头前k个字符和第i+1个字符的前k个字符都是一一对应的.当第k个字符和第i个字符不一样时,k就得回溯,然后再进行对比.
扩展
1.kmp算法求出来的next数组可以用来求一个字符串的最小循环节.最小循环节长度为(len-next[len]),由该字符串前(len-next[len])个字符构成.
2.如果kmp是为了查找字符串的话,可以注意下假设第i个字符前面有k个字符和字符串前k个字符一样,而第i个字符又和第k+1个字符一样,那么当第i个字符匹配不到的话,就不需要回溯到第k+1个字符了,因为第i个字符和第k+1个字符一样,所以直接令next[i]=next[k]行了.
1 if(k==-1||s[i]==s[k]) 2 { 3 if(s[++i]==s[++k]) next[i]=next[k]; 4 else next[i]=k; 5 }