KMP模版及解析

来源:互联网 发布:淘宝实时访客其他来源 编辑:程序博客网 时间:2024/06/14 13:30

九野的博客,转载请注明出处 http://blog.csdn.net/acmmmm/article/details/9863495

f[]是失配数组(顾名思义 失配数组记录的就是,原串和模式串若发生不匹配时,模式串应该调回到最近可能匹配的位置)

当P[i]与T[k]不一样时(不一样叫失配)

要么从头开始和T[k]匹配(朴素算法就是这样做的,不一样时用P[0]和当前的T[k]匹配)

KMP是用最可能P[f[?]]匹配,?是用find()函数中的while寻找最近的,与当前的T[k]相同的字符

如 

T:a s d f g w s x f g a s d c a s d c 

P:a s d c c

d位置时 c d失配 则寻找一个P[i]使得P[i]=’d’P[i]前面的和d 前面的相同

显然这里是没有的,所以f[c]=0,表示不需要管d这点了,直接匹配下面的,因为d这点不满足上面绿色字体的条件(这里绿色字体的条件就是KMP的失配数组f寻找的目的)

T:a s d f g w s x f g a a k a a a s d c 

P:a a k a a g

这里失配的是P[5](g)和T[16](k)则满足上面绿色字体的条件就是P[2],则显然f[5]=2

f[]用getFail()得到的结果是 {0,0,1,0,1,2}

显然:a a k和a a g 中 a a是循环的,其实f[]数组就是求个P串的前缀循环节


#include <stdio.h>#include <string.h>char T[10000],P[100];//从0开始存int f[100];//记录P的自我匹配void getFail(){int m=strlen(P);f[0]=f[1]=0;for(int i=1;i<m;i++){int j=f[i];while(j&&P[i]!=P[j])j=f[j];f[i+1]= P[i]==P[j] ? j+1 : 0;}}int find(){int len1=strlen(T),len2=strlen(P);getFail();int j=0;for(int i=0;i<len1;i++){while(j&&P[j]!=T[i])j=f[i];if(P[j]==T[i])j++;//到这一步,j就代表 T[i]已经匹配了前面j个P的字符串if(j==len2)printf("%d\n",i-len2+1);}}