标签:blog ar strong div 问题 sp log on c
KMP算法中,如果当前字符匹配成功,即S[i]==T[j],令i++,j++,继续匹配下一个字符;如果匹配失败,即S[i] != T[j],需要保持i不变,并且让j = next[j],这里next[j] <=j -1,即模式串T相对于原始串S向右移动了至少1位(移动的实际位数j - next[j] >=1
当匹配到S[i] != P[j]的时候有 S[i-j…i-1] = P[0…j-1]. 如果下面用j_next去匹配,则有P[0…j_next-1] = S[i-j_next…i-1] = P[j-j_next…j-1]
next[j]=k>0时,表示P[0...k-1]=P[j-k,j-1]。同时当P数组的第J个元素与S对应的元素不匹配,让P里面的第NEXT[J]与这个S元素尝试匹配
因此KMP算法的思想就是:在匹配过程称,若发生不匹配的情况,如果next[j]>=0,则目标串的指针i不变,将模式串的指针j移动到next[j]的位置继续进行匹配;若next[j]=-1,则将i右移1位,并将j置0,继续进行比较。
那么这个next数组如何得到,这个NEXT只与P数组有关,与S无关。
按照递推的思想:
根据定义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;
2)若P[j]!=P[k],则可以把其看做另一个模式匹配的问题,即匹配失败的时候,k值如何移动才能使得P[...K‘]=P[...J],显然K‘=next[k]。
void getNext(char *p,int *next)
{
int j,k;
next[0]=-1;
j=0;
k=-1;
while(j<strlen(p)-1)
{
if(k==-1||p[j]==p[k])
//匹配的情况下,p[j]==p[k];j等于0、k等于-1的时候表示第1(J++后等于1)个元素不匹配,只能尝试第0个元素,由于前面没有别的元素,假定前面所有元素全部相等
{
j++;
k++;
next[j]=k;//当J匹配不成功时候的备用元素
}
else //p[j]!=p[k]
k=next[k];
}
}
KMP本身算法:
int KMPMatch(char *s,char *p)
{
int next[100];
int i,j;
i=0;
j=0;
getNext(p,next);
while(i<strlen(s))
{
if(j==-1||s[i]==p[j])
{
i++;
j++;
}
else
{
j=next[j]; //消除了指针i的回溯
}
if(j==strlen(p))
return i-strlen(p);
}
return -1;
}
标签:blog ar strong div 问题 sp log on c
原文地址:http://www.cnblogs.com/notlate/p/3965427.html