参考博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html
KMP算法用来匹配两个字符串,即b串是否为a的子串。
普通算法的复杂度为O(n*m),KMP算法的复杂度为O(n+m)。
用 i 计数 a 串的位置,用 j 计数 b 串的位置。
普通算法:
如果 a[i] != b[j] ,则 i 回溯,j=0。
KMP算法:
KMP算法和普通算法的区别在于,KMP消除的 i 的回溯,只需确定下次匹配 j 的位置即可。在KMP算法中引入了next数组,为了确定匹配不成功时,下次匹配时 j 的位置。next[j]的值表示P[0...j-1]中最长后缀的长度等于相同字符序列的前缀。
对于next[]数组的定义如下:
1) next[j] = -1 j = 0
2) next[j] = max(k): 0<k<j P[0...k-1]=P[j-k,j-1]
3) next[j] = 0 其他
如:
P a b a b a
j 0 1 2 3 4
next -1 0 0 1 2
即next[j]=k>0时,表示P[0...k-1]=P[j-k,j-1]
KMP算法的思想就是:在匹配过程称,若发生不匹配的情况,如果next[j]>=0,则目标串的指针i不变,将模式串的指针j移动到next[j]的位置继续进行匹配;若next[j]=-1,则将i右移1位,并将j置0,继续进行比较。
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; }
求next数组
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++; k++; next[j]=k; } else //p[j]!=p[k] k=next[k]; } }