一、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 如果匹配失敗,則將關鍵字向右滑動乙個字元,從頭開始匹配關...