解析KMP模式匹配演算法

2021-08-06 02:18:17 字數 2261 閱讀 6514

程杰《大話資料結構》那本書中,「串」那一章的最後有個特別厲害的演算法——kmp模式匹配演算法。模式匹配演算法其實就是,在乙個主字串當中尋找某子字串,並返回子字串在主字串中的位置。

這個kmp模式匹配演算法可真的是狂拽酷炫吊炸天,核心**僅僅四五行,而我看了兩個多小時才看明白(允許我在這裡賣弄一下我的「笨」)。kmp演算法的核心思想很好理解,但其中有個求next陣列的處理技巧,比較令人費解。下面將自己的理解和分析進行說明,重點說「求next陣列的處理技巧」的那部分,希望對其他人理解kmp演算法有所幫助。

注:我將書中**進行了修改,去除了字串中第乙個字元為字串長度的情況,因為string的字串長度可以通過size()求出。

求next陣列的

問題抽象

:給定乙個字串,求

前子字串和

後子字串

匹配的最大

位數,再+1,例如「

abcexyz

abc」的前子

字串「abc」==後子

字串「abc」,即該字串前後

子字串匹配的最大位數==3,+1==4。next陣列中的每個元素next[ j ]是指給定字串的

前 j 個

字元(0~j-1)構成的字串,的前後子

字串匹配的

最大位數+1。例如字串「ababaaaba」的next=,其中next[4]==3,前4個字元「

abab」的

前後子字串匹配的

最大位數==2,+1==3

。令人費解的數學公式表達如下:

先上**(next陣列的處理技巧**),再解釋。

// 演算法核心部分

void get_next(const string& str, vector& maxk)

}

解釋兩點:

1.「不能突增原理」,即maxk[i+1]比maxk[i]最多大1

。假設存在maxk[i+1]比maxk[i]大,且》1,成立。因為前i個字元的前字尾匹配最大個數+1==maxk[i],前 i+1 個字元的前字尾匹配

最大個數+1==maxk[i+1]。我們從前 i+1 個字元的情況倒著往前 i 的情況進行推導,令k=maxk[i+1] -1,當maxk[i+1]>maxk[i]時,那麼前i+1 個字元有k個匹配,此時前 i 個字元有k-1個匹配一定成立。則前 i 個字元的前字尾匹配

最大個數k-1 再+1==k == maxk[i+1]-1 >

maxk[i],與「最大」為maxk[i]矛盾。所以,不能突增,maxk[i+1]比maxk[i]最多大1。

2.回溯,前 ki-1 個字元構成的字串的 前後匹配的最大個數,是目前 前 i 個字元構成的字串的 前後匹配的 「次大」個數。同樣假設「次大」個數  >  前 ki-1 最大個數,會得到與 「前 ki-1 個字元構成的字串的 前後匹配的最大個數」 相矛盾的結果。

「求next陣列的處理技巧」的亮點在於,在求當前 前 i 個字元構成的字串的 前後最大匹配的情況時,它利用之前已經計算過的資訊來計算當前能夠匹配的最大可能,減少了很多單獨求該字串的最大匹配情況 的重複的工作,所以「很高效」。另外,在kmp演算法使用next陣列時,也減少了很多重複性的工作,所以kmp演算法「很高效」。

kmp模式匹配演算法的其它部分**:

#include #include #include using namespace std;

void get_next(const string& str, vector& vec);

void get_nextval(const string& str, vector& vec);

int index_kmp(string s, string t, int pos);

int main()

// 演算法核心部分,改進版

void get_nextval(const string& str, vector& maxk)

else

ki = maxk[ki - 1]; }}

int index_kmp(string s, string t, int pos)

else

j = next[j] - 1;// 改了 -1

} if (j >= t.size())// 改了 >=

return i - t.size();

else

return -1;// 改了 -1

}

串的模式匹配演算法 KMP演算法解析

kmp演算法是一種改進的字串匹配演算法,由d.e.knuth,j.h.morris和v.r.pratt同時發現,因此人們稱它為克努特 莫里斯 普拉特操作 簡稱kmp演算法 kmp演算法的關鍵是利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現乙個next 函式...

模式匹配 KMP演算法

字串匹配演算法 include includeusing namespace std define ok 1 define error 0 define overflow 2 typedef int status define maxstrlen 255 使用者可在255以內定義最長串長 typed...

模式匹配KMP演算法

前些日子在為目前該學習什麼而苦惱,就問了一下已經從事多年軟體開發的表哥,他說乙個程式設計師要走的遠,就要學好資料結構和演算法,於是我就重新開始學習資料結構和演算法了 拿起以前上過的資料結構看,看到第四章串的模式匹配時,頗感興趣,就寫了一下程式,實踐了一下。感覺還蠻爽,於是就把以下幾個重要的函式放在此...