程杰《大話資料結構》那本書中,「串」那一章的最後有個特別厲害的演算法——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演算法
前些日子在為目前該學習什麼而苦惱,就問了一下已經從事多年軟體開發的表哥,他說乙個程式設計師要走的遠,就要學好資料結構和演算法,於是我就重新開始學習資料結構和演算法了 拿起以前上過的資料結構看,看到第四章串的模式匹配時,頗感興趣,就寫了一下程式,實踐了一下。感覺還蠻爽,於是就把以下幾個重要的函式放在此...