标签: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