字串匹配演算法之KMP總結
字串匹配有很多方法,比如暴力,雜湊等等,還有一種廣為人知的演算法
。
一.問題引入
需要一種演算法,能夠線上性的時間內判斷 是否是字串 的字串,並要求返回字串a在b中匹配的所有位置
思考暴力。
列舉i從 表示 匹配的左端點,然後 的判斷 是否與 匹配。
我們很容易發現這樣的方法在極端資料下跑的很慢,比如:
aaaaaaaaaaaaaaaaaab
aaaaab
每次要匹配到a最後一個位置才發現不相等。時間複雜度
當然此問題亦可以通過雜湊解決,筆者在此不多贅述
接下來我們就講神奇的
演算法
二.演算法概述
演算法,又稱模式匹配演算法,是一種能夠高效,準確的處理字串匹配的演算法
KMP演算法基本分為兩部:
1.首先是對 陣列(模式串)進行自我匹配。
建立一個 陣列, 表示以 結尾的非字首字串與A的字首能夠匹配的最大長度。
其中“以 結尾的非字首字串”通俗的說就是非字首的字尾,比如aab的非字首的字尾就是
且
舉個例子:
設 串為 ,A陣列的next[7]應該為5,推導過程如下:
發現有三個可行的j滿足 :
與
匹配;
與
匹配;
與
匹配;
其中 最大的是第 個為
如何更快的計算 陣列?
不妨設 都已求出,通過上述過程知
接下來考慮next[8]
發現 而 ,所以 不等於
那麼只好將匹配長度 縮短
根據上面的結論我們知道 好可以等於 和 ,嘗試延伸到
但是我們發現 與 和 都不匹配,於是只能從頭匹配,
那我們怎麼讓程式知道當我們發現 時該去匹配 和 呢?
說明從 往前 個字元是與 匹配的。那我們下一步要尋找的也就是 之前的 個字元與 相匹配,那麼 往前 個字元是與 匹配的。這個 的答案就是 ,其實就是