談談KMP算法

KMP算法的資料網上已經一大把了,主要用來解決某個文本片斷是否包含另外一個子串問題。這裏假設文本片斷的長度n大於子串長度m,如:算法

文本串爲ABCDABGHIJK指針

子串爲   ABCDABE字符串

在傳統的暴力解法中當子串的E與主串的G不匹配時,將文本串從B開始、子串從頭開始從新匹配,這樣的時間複雜度爲(n-m+1)*m,很顯然效率是比較低的。效率

KMP算法的思想是當子串的E不匹配時,文本串保持在G位置,子串從C位置開始匹,關鍵就是要知道:方法

一、爲何是C這個位置?集合

二、如何求C這個位置?時間

先說第一個問題:直觀的看是由於C前面的AB與G前面的AB正好可以匹中。但實際上就像採用暴力法解決時,本質上是在查找子串ABCDABE與剩餘文本串BCDABGHIJK的第一個能找到子串最長前綴AB的位置,因爲KMP算法不想讓未匹中字符G的位置進行回溯即已經固定,因此就等價於查找子串ABCDABE與剩餘文本串BCDAB的最長公共前綴問題。因爲最長公共前綴是AB因此子串從C位置開始匹。字符

再說第二個問題:查找子串ABCDABE與剩餘文本串BCDAB的最長公共前綴問題等價於計算子串ABCDA與剩餘文本串BCDAB的最長公共前綴問題(由於最長公共前綴的長度必定是<=剩餘文本串BCDAB的長度),所以也就等價於計算字符串ABCDAB的最長公共先後綴長度也就是計算集合(ABCDA、ABCD、ABC、AB、A)與集合(BCDAB、CDAB、DAB、AB、B)的交集中字符長度最長的字符即AB。

求解的方法比較簡單將ABCDA與BCDAB比較、ABCD與CDAB比較、ABC與DAB比較、AB與AB比較、A與B比較便可。

實際上子串的每一個字符都要求出當不匹配時指針應該停留的位置,這個在匹配前須要進行預處理,預處理的方法就是求解第二個問題的方法。

相關文章
相關標籤/搜索