http://www.cnblogs.com/ziyi--caolu/archive/2013/01/01/2841548.html
写KMP的不错的博客。
KMP算法,是字符串匹配O(N)的算法,和朴素字符串匹配的区别在于:匹配失败时会跳过已知不可能匹配的位置。
朴素字符串匹配: 原串S=ababcababa,子串P=ababa。
ababcababa ababcababa ababcababa ababcababa
ababa ababa ababa ababa
可以看到:子串P中有ab 重复,一旦匹配失败,子串不必只移动一位,而是移动到下一个 需要匹配的位置
KMP算法引入了next数组,表示匹配失败后 应该匹配子串的哪个位置,通过对子串的预处理得到next数组。
这个思想也被用在了其他算法中,比如AC自动机- - 我是懵逼的
next[i]=k表示 P[0~k-1] ==P[i-k~i-1] 这两段字符串相同!
next数组的定义:
1:j==0 next[0]=-1;
2: next[j]=max k(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
KMP的过程:if(不匹配)
if(next[j]==-1) i后移,j置0;
else {j=next[j];i不变;}
i 指向原串S的匹配位置,j 指向子串P的匹配位置.
求next数组的过程:根据定义来求。
next[0]=-1;
if(P[j]==P[k]) next[j+1]=next[j]+1 (k=next[j])
else 当前指针指向下一个需要匹配的位置 ,即k=next[k]
不允许出现next[j]=-1
FIND NEXT:
void getnxt() { nxt[0]=-1; int i=0,j=-1; while(i<m) { if(j==-1||b[i]==b[j]) { i++;j++; nxt[i]=j; } else j=nxt[j]; } }
KMP:
int kmp() { getnxt(); int i=0,j=0; while(i<n) { if(a[i]==b[j]||j==-1) { i++;j++; } else j=nxt[j]; if(j==m)return i; } return -1; }