(1) next数组中存的就是匹配串中前缀和后缀相等的最大长度
比如 p=a b c a b d
如果d失配了那么当前指针j就可以从原来的5变为next[5]=2;,也就是说下一次从c开始与匹配串匹配
为什么next[5]=2呢,因为串p中d的前缀为a b c ,后缀为a,b
ab==ab长度为2
下面是next数组的求法
/*
根据定义next[0]=-1,假设next[j]=k, 即P[0...k-1]==P[j-k,j-1]
1)若P[j]==P[k],则有P[0..k]==P[j-k,j],很显然,next[j+1]=next[j]+1=k+1;(此处有误,如果p[j+1]==p[k+1]的话那么next[j+1]=next[k+1])
2)若P[j]!=P[k],则可以把其看做模式匹配的问题,即匹配失败的时候,k值如何移动,显然k=next[k]。
*/
void get_next(char *s,int *next)
{
int len=strlen(s);
int j=0,k=-1;
next[0]=-1;
while(j<len)
{
if(k==-1 || s[j]==s[k])
{
j++;
k++;
if(s[j]==s[k])
next[j]=next[k];
else
next[j]=k;
}
else
k=next[j];
}
}
弄懂了next的意义和求法之后KMP算法就很容易能够写出来了
int KMP(char *p,char *t)
{
int len=strlen(t);
int len2=strlen(p);
int i=0,j=0;
while(i<len)
{
if(j==-1 || t[i]==p[j])
{
i++;
j++;
}
else
j=next[j];
if(j==len2)
return i-len2; //匹配成功返回初始下标
}
return -1; //匹配失败
}