KMP算法簡介
KMP算法是在基礎的模式匹配算法的基礎上進行改進得到的算法,改進之處在於:每當匹配過程中出現相比較的字符不相等時,不需要回退主串的字符位置指針,而是利用已經得到的部分匹配結果將模式串向右“滑動”盡可能遠的距離,再繼續進行比較。在KMP算法中,依據模式串的next函數值實現字串的滑動,本隨筆介紹next函數值如何求解。
next[ j ]求解
將 j-1 對應的串與next[ j-1 ]對應的串進行比較,若相等,則next[ j ]=next[ j-1 ]+1;若不相等,則將 j-1 對應的串與next[ next[ j-1 ]]對應的串進行比較,一直重復直到相等,若都不相等則為其他情況
題1
在字符串的KMP模式匹配算法中,需先求解模式串的函數值,期定義如下式所示,j表示模式串中字符的序號(從1開始)。若模式串p為“abaac”,則其next函數值為()。
解:j=1,由式子得出next[1]=0;
j=2,由式子可知1<k<2,不存在k,所以為其他情況即next[2]=1;
j=3,j-1=2 對應的串為b,next[2]=1,對應的串為a,b≠a,那么將與next[next[2]]=0對應的串進行比較,0沒有對應的串,所以為其他情況,也即next[3]=1;
j=4,j-1=3 對應的串為a,next[3]=1,對應的串為a,a=a,所以next[4]=next[3]+1=2;
j=5,j-1=4 對應的串為a,next[4]=2,對應的串為b,a≠b,那么將與next[next[4]]=1對應的串進行比較,1對應的串為a,a=a,所以next[5]=next[2]+1=2;
綜上,next函數值為 01122。
題2
在字符串的KMP模式匹配算法中,需先求解模式串的函數值,期定義如下式所示,j表示模式串中字符的序號(從1開始)。若模式串p為“tttfttt”,則其next函數值為()。
解:
j=1,由式子得出next[1]=0;
j=2,由式子可知1<k<2,不存在k,所以為其他情況即next[2]=1;
j=3,j-1=2 對應的串為t,next[2]=1,對應的串為t,t=t,所以next[3]=next[2]+1=2;
j=4,j-1=3 對應的串為t,next[3]=2,對應的串為t,t=t,所以next[4]=next[3]+1=3;
j=5,j-1=4 對應的串為f,next[4]=3,對應的串為t,f≠t,那么將與next[next[4]]=2對應的串進行比較,2對應的串為t,f≠t。繼續和next[2]=1對應的串對比,序號為1也就是第一個串對應的串為t,同樣f≠t,到此所以對比已結束,均不相等,所以為其他情況,next[5]=1;
j=6,j-1=5 對應的串為t,next[5]=1,對應的串為t,t=t,所以next[6]=next[5]+1=2;
j=7,j-1=6 對應的串為t,next[6]=2,對應的串為t,t=t,所以next[7]=next[6]+1=3;
綜上,next函數值為0123123。
最后附上求模式串的next函數,如下
*求模式串p的next函數值,並存入數組next
void Next(char *p,int next[]) { int i,j,len; len=strlen(p); i=0; next[0]=-1; j=-1; while(i<len) { if(j==-1||p[i]==p[j]){++i;++j;next[i]==j;} else j=next[j]; } }