kmp改進演算法
⑴ 模式p='abcaababc '的KMP演算法和KMP,並改進演算法的匹配過程!
求子串next[j]值的演算法:
void GetNext(String T, int next[])
{ int j = 1, k = 0;
next[1] = 0;
while(j < len(T)){
if( k == 0 || T[j]==T[k])
{j++; k++; next[j]=k; }
else k = next[k];
}
}
KMP 演算法的自然語言描述
設s為主串,t為模式串,設i為主串s當前比較字元的下標,j為模式串t當前比較字元的下標,令i和j的初值為pos和1。當si = tj時,i和j分別增1再繼續比較;否則 i不變,j改變為next[j]值(即模式串右滑)後再繼續比較。依次類推,直到出現下列兩種情況之一:
一是 j退回到某個j=next[j]值時有si = tj ,則 i和j分別增1後再繼續比較;
二是j退回到j=0時,令主串和子串的下標各增1,隨後比較si和t1 。這樣的循環過程一直進行到變數大於等於s的長度或變數j大於等於t的長度為止。
int KMPIndex(String S, int start,String T, int next[ ])
{
int i = start, j=1;
while ( i <= S[0] && j< T[0]) {
//不失配則繼續比較後續字元
if (j == 0 || S [i] = = T[j] ) {i++; j++ }
//特點:S的i指針不回溯,而且從T的k位置開始匹配
else j=next[j];
}
if (j >= T[0]) return ( i-T(0) );
else return -1;
}
⑵ kmp演算法的優化
KMP演算法是可以被進一步優化的。
我們以一個例子來說明。譬如我們給的P字元串是「abcdaabcab」,經過KMP演算法,應當得到「特徵向量」如下表所示: 下標i 0 1 2 3 4 5 6 7 8 9 p(i) a b c d a a b c a b next[i] -1 0 0 0 0 1 1 2 3 1 但是,如果此時發現p(i) == p(k),那麼應當將相應的next[i]的值更改為next[k]的值。經過優化後可以得到下面的表格: 下標i 0 1 2 3 4 5 6 7 8 9 p(i) a b c d a a b c a b next[i] -1 0 0 0 0 1 1 2 3 1 優化的next[i] -1 0 0 0 -1 1 0 0 3 0 (1)next[0]= -1 意義:任何串的第一個字元的模式值規定為-1。
(2)next[j]= -1 意義:模式串T中下標為j的字元,如果與首字元
相同,且j的前面的1—k個字元與開頭的1—k
個字元不等(或者相等但T[k]==T[j])(1≤k<j)。
如:T=」abCabCad」 則 next[6]=-1,因T[3]=T[6]
(3)next[j]=k 意義:模式串T中下標為j的字元,如果j的前面k個
字元與開頭的k個字元相等,且T[j] != T[k] (1≤k<j)。
即T[0]T[1]T[2]。。。T[k-1]==
T[j-k]T[j-k+1]T[j-k+2]…T[j-1]
且T[j] != T[k].(1≤k<j);
(4) next[j]=0 意義:除(1)(2)(3)的其他情況。
補充一個next[]生成代碼: voidgetNext(constchar*pattern,intnext[]){next[0]=-1;intk=-1,j=0;while(pattern[j]!='