KMP是判断字符串匹配的算法。
目标:找到字符串中与模板串相同子串的匹配位置/次数
理解:状态机,状态转移图,失配后不从头匹配。或者理解为,找失配函数=找最长前后缀
f[i] 为失配函数,T 为模板串,P 为需要匹配的串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| void match(char *T,char *P,int *f) { int l1=strlen(T),j=-1,l2=strlen(P); for(int i=0;i<l2;i++) { while(~j&&T[j+1]!=P[i]) j=f[j]; if(T[j+1]==P[i]) j++; if(j==l1-1) { printf("%d\n",i-j+1); j=f[j]; } } }
void get_f(char *T,int *f) { int len=strlen(T),j=-1; f[0]=f[1]=-1; for(int i=1;i<len;i++) { while(~j&&T[j+1]!=T[i]) j=f[j]; if(T[j+1]==T[i]) j++; f[i]=j; } }
|
- 最大公共前后缀->得到最小循环子串(这里原串可以是不完整的)
- 最长前后缀,最短前后缀,重合前后缀,不重合前后缀的递推相关问题注意优化,跳fail的时候,不一定每次都从当前位置往前跳,类比kmp的原理可以考虑能不能从上一位遗留的j 更新