串的模式匹配 KMP演算法

2021-06-15 07:23:03 字數 1642 閱讀 5016

一、kmp演算法的思想

由d.e.knuth、j.h.morris和v.r.pratt共同提出了乙個改進演算法,消除了brute-force演算法中串s指標的回溯,完成串的模式匹配。時間複雜度為o(s.curlen+t.curlen),這就是knuth-morris-pratt演算法,簡稱kmp 演算法。

1、kmp演算法形成過程:

若s[i]≠p[j] ,為使主串指標 i不回溯,可以從模式串的第k個字元開始比較,即讓 j重新賦值k。k值如何確定?

若s[i]≠p[j] , j重新賦值為 k,必有:p1p2 …..pk -1=si -k +1 si -k +2 ……si -1.

同樣必有:pj -k+1pj -k+2 ……pj -1= si -k +1 si -k +2 ……si -1.因此pj -k+1pj -k+2 ……pj -1= p1p2 …..pk -1.

2、kmp演算法的基本思想:

設目標串為s,模式串為t

i、j 分別為指示s和t的指標,i、j的初值均為0。

若有 si = tj,則i和j分別增1;否則,i不變,j退回至j=next[j]的位置 ( 也可理解為串s不動,模式串t向右移動到si與tnext[j]對齊 );

比較si和tj。若相等則指標各增1;否則 j 再退回到下乙個j=next[j]的位置(即模式串繼續向右移動 ),再比較 si和tj。

依次類推,直到下列兩種情況之一:

1)j退回到某個j=next[j]時有 si = tj,則指標各增1,繼續匹配;

2)j退回至 j=-1,此時令指標各增l,即下一次比較 si+1和 t0。

3、next[j]的求法

由定義: next[0]=-1;

設 next[j]= k,則有p0p1p2 …..pk -1= pj -kpj -k+2 ……pj -1. next[j+1]= ?         

1)若 pk=pj,必有p0p1p2 …..pk -1pk= pj -kpj -k+2 ……pj -1pj,因此 next[j+1]=k+1=next[j]+1;

2)  若 pk≠pj,則p0p1p2 …..pk -1pk≠pj -kpj -k+2 ……pj -1pj.在當前匹配的過程中,已有p0p1p2 …..pk -1= pj -kpj -k+2 ……pj -1。若pk≠pj,應將模式向右滑動至以模式中的next[j]= k個字元和主串中的第j個字元相比較。若  k』=next[k],且pk』=pj,則說明存在乙個長度為k』的子串相等:

p0p1p2 …..pk』 -1= pj –k』pj –k』+2 ……pj -1且滿足: 0=t.length) // 匹配成功

return i-t.length;

else

return 0;

}//index_kmp

void outprints(hstring &t)

//outprints

void inputs(hstring &s)

//inputs

int main()

六、next[j]求法的改進

brute-force演算法的時間複雜度為o(n*m),但是實際執行近似於o(n+m)。kmp演算法僅當模式與主串之間存在許多「部分匹配」的情況下,才會比b-f演算法快。kmp演算法的最大特點是主串的指標不需要回溯,整個匹配過程中,過主串僅需從頭到尾掃瞄一次,對於處理從外設輸入的龐大檔案很有效,可以邊讀邊匹配。

KMP 模式串匹配演算法

這兩天讀了july的kmp,覺得很受益,寫下以作備忘。kmp最重要的就是求出next陣列,而next陣列則是通過不斷比較 str2 k 與 str2 j 來確定下乙個字元對應的 next數值 相等則直接next j k 不相等則令k next k 進行遞推直到出現 str2 k str2 j 相等的...

串 KMP模式匹配演算法

樸素模式匹配演算法就是簡單的二重迴圈,第一重迴圈主串s從1到n,然後第二重迴圈子串t從1到m進行匹配判斷,時間複雜度為o n m 1 m kmp演算法的核心思想是 第一 如果子串前r個字元均不相等,且子串前r個字元與主串某連續的r個字元匹配,但子串第r 1就不匹配了,則主串的匹配下標可以直接向前跳r...

模式串匹配 KMP演算法

kmp是對字首暴力搜尋的改進,基於的想法其實是很樸素的。首先我們來看一下暴力搜尋。char bf char src,char pattern else if pattern temp 0 return src else return null 如果匹配失敗,則將關鍵字向右滑動乙個字元,從頭開始匹配關...