KMP詳細解釋及KMP演算法模板

2021-10-25 02:55:44 字數 3030 閱讀 7934

kmp是什麼,kmp解決什麼型別的問題

kmp全稱為knuth morris pratt演算法,是一種高效的字串匹配演算法,尋找乙個字串中是否包含另乙個字串,例如

char

*s =

"ababababcab"

;char

*p =

"ababc"

;

s為模板串(主串),p為子串,在s中找到p的位置

暴力匹配演算法 o(n*m)

暴力匹配演算法不做過多解釋,舉個例子即可

匹配到第4個字元時匹配失敗則i+1繼續向後匹配

ababababcab

ababc

則i+1繼續向後匹配

ababababcab

ababc

匹配失敗繼續向後匹配直到如圖

ababababcab

ababc

匹配成功

此時我們可以發現當我們已經匹配了一部分字串但下乙個字元不相等時,我們還有一些資訊可以利用,比如

ababababcab

ababc

這時已經匹配了4個字元相等,我們可以根據這個資訊來簡化演算法時間複雜度,這時我們引入kmp演算法

kmp演算法o(n+m)

我們可以利用已經匹配的字元來簡化列舉過程,當已經匹配成功了4個字元時,我們是不是可以讓字串向後移動來使得子串和模板串繼續匹配?

例如

ababababcab

ababc

此時我們讓子串向後移動而模板串不動,使得模板串可以繼續向後繼續匹配

ababababcab

ababc

此時匹配成功則繼續向後匹配

而這樣的移動就是kmp的next陣列的用處

next陣列的含義是乙個固定字串的最長字首和最長字尾相同的長度,並且長度小於(不能等於)固定字串本身,使得當匹配失敗我們讓子串向後移動最少的距離使模板串可以繼續匹配,也就是說在某個字元失配時,該字元對應的next 值會告訴你下一步匹配中,子串應該跳到哪個位置

例如

假設我們在模板串的i位置和字串的j+1的位置匹配失敗,此時我們將字串向後移動

j是我們匹配成功的最後乙個字元

我們令j = next[j], 回憶一下next的陣列含義next陣列的含義是乙個固定字串的最長字首和最長字尾相同的長度,此時

字串移動到p2的狀態,而這時p1,p2的綠色部分相等才能和模式串繼續匹配,我們還可以發現

此時p1,p2的這兩個綠色部分也是相等的,所以p中的綠色部分是相同的

所以也說明了next陣列含義是乙個固定字串的最長字首和最長字尾相同的長度,讓前字尾相同我們才能使模板串繼續匹配,而最長則保證了我們能找到所有的與模板串匹配的子串同時也能使子串與模板串盡快匹配,我們先不管next陣列是怎麼求得的我們先利用next陣列實現kmp演算法

kmp演算法流程

// s是模板串,p是子串,n是s的長度,m是p的長度

// 匹配

for(

int i =

1, j =

0; i <= n; i ++

)//由於我們令i與j+1匹配,所以i初始化為1, j初始化為0, 同時s與p的第乙個字元在1位置,不在0位置

}

next陣列實現

再強調一遍next陣列含義next陣列的含義是乙個固定字串的最長字首和最長字尾相同的長度,由於next陣列只與子串有關所以我們應該先對子串進行預處理,處理出next陣列,處理next陣列方式也與kmp實現過程類似。我們把p子串當作模板串和子串進行匹配,假設我們當前要求next[i]的值,匹配到如下情況

當p[i] == p[j+1]時,則j+1的值是不是就是next[i]的值,也就是長度為i的子串最長字首和最長字尾相同的長度,如圖

如果p[i] != p[j+1],同kmp過程,1~j這一段是匹配的,則令j = next[j],繼續找下乙個能匹配的位置,由於我們的j是從p串的開頭位置開始,所以只要當p[i] == p[j+1]時,next[i] = j + 1.

上**

//求模式串的next陣列:

for(

int i =

2, j =

0; i <= m; i ++

)//next[1] = 0, 所以i從2開始

kmp完整模板
// s是模板串,p是子串,n是s的長度,m是p的長度

//求模式串的next陣列:

for(

int i =

2, j =

0; i <= m; i ++

)// 匹配

for(

int i =

1, j =

0; i <= n; i ++

)}

模板來自acwing:acwing模板

KMP演算法解釋

有些演算法,適合從它產生的動機,如何設計與解決問題這樣正向地去介紹。但kmp演算法真的不適合這樣去學。最好的辦法是先搞清楚它所用的資料結構是什麼,再搞清楚怎麼用,最後為什麼的問題就會有恍然大悟的感覺。我試著從這個思路再介紹一下。大家只需要記住一點,pmt是什麼東西。然後自己臨時推這個演算法也是能推出...

KMP演算法詳解及模板

kmp 演算法是用來解決單模匹配問題的一種演算法。如果暴力的進行單模匹配,那麼時間複雜度為o nm kmp 演算法通過對模式串的預處理優化了複雜度。為了敘述方便,設模式串長度為n,主串長度為m。將模式串稱為s1,主串稱為s2,下標從1 開始。我們首先對模式串預處理出乙個next 陣列。next i ...

演算法 KMP演算法 解釋

1.詳解kmp演算法 2.大話資料結構 3,kmp演算法易懂版 kmp演算法由d.e.knuth j.h.morris和v.r.pratt發表的模式匹配演算法。kmp演算法要解決的問題就是在字串 也叫主串 中的模式 pattern 定位問題。例子 輸入 主串 s abeabx 子串 t abx 輸出...