樸素的模式匹配和改進的模式匹配(kmp)演算法說明
lewislau
前言:最近複習資料結構,以前老師講的時候居然忽略了串。汗,我們學校的確牛b。某仁兄告訴我,kmp基本是資料結構裡面難度比較大的演算法了,所以掌握了它,至少從心理上給我了很大的鼓舞,但是這個演算法是我詢問老師才掌握的,呵呵。言規正傳,開始說kmp演算法。
在說改進的模式匹配(kmp)演算法之前我們先說樸素的模式匹配:
其實很簡單,就是兩個字串逐位比較。在模式匹配中:我們假定字串p在字串t中查詢是否有匹配的。此時,稱p為模式(pattern)字串,稱t為目標(target)字串。
ok,我一般比較喜歡以例項說明問題。
t: a b d a b d a b c
p: a b d a b c
樸素的模式匹配演算法
樸素的模式匹配演算法就是用p和t依次比較,即為:
第一趟比較: t: a b d a b d a b c
p: a b d a b c
發現第6個元素(下標為5)d和c不相等,第一趟結束,此時比較了6次(6個元素)。
第二趟比較: t: a b d a b d a b c
p: a b d a b c
第乙個元素就不相等,第二趟結束,此時比較了1次(1個元素)。
第三趟比較: t: a b d a b d a b c
p: a b d a b c
第乙個元素就不相等,第三趟結束,此時比較了1次(1個元素)。
第四趟比較: t: a b d a b d a b c
p: a b d a b c
第乙個元素相等,第二個元素也相等,第
三、四、五、六都相等,匹配成功,第四趟結束,此時比較了6次(6個元素)。
匹配成功,共比較14次。但是這個是我們理想狀態下的匹配方案,實際中字串的長度遠遠不止這些。這種演算法是一種帶回逆的演算法,成為樸素的模式匹配演算法。
假定:目標t長度為n,模式p長度為m,那麼它的最壞情況下,會比較次數可達到:
(n - m + 1)*m 次;在眾多場合下m遠遠小於n,它的時間複雜度為o(n * m)。
改進的模式匹配(kmp)演算法
kmp演算法就是消除了樸素匹配的回逆,利用乙個失效函式(failure function)替代直接的回逆。思路如下:
第一趟比較: t: a b d a b d a b c
p: a b d a b c
發現第6個元素(下標為5)d和c不相等。此時,進入乙個p串的處理:
此時取出p串, a b d a b c 因為是c不和d不匹配,去掉此項,獲得
a b d a b
此時判斷 a b d a 是否與 b d a b 相等? 不等,進入下一輪判斷
此時判斷 a b d 是否與 d a b 相等? 不等,進入下一輪判斷
此時判斷 a b 是否與 a b 相等? 相等,結束第一趟總體判斷。
(先不要急,接下來我就會說為什麼這樣匹配和這樣匹配的用途!)
以上就是kmp的流程,為什麼要這樣做?在一些串中,目標串會遠遠長於模式串,如果每次都江模式串和目標串一一比較。此時時間複雜度當增加,而且在模式串中會出現很多的無效匹配,相當於無用功。但是假如先在模式串中進行比較,因為模式串會遠遠短於目標串,所以會相當減少時間複雜度。
以上是kmp的簡單介紹,有機會會整理出詳細演算法及其優勢!
其他不想多說,只想說明「演算法是程式的靈魂!」這一古老而經典的話!!
樸素的模式匹配演算法
有時,我們需要在乙個長串t中尋找固定長度的子串s,找出子串在原串中的位置,對於這種操作,我們稱之為串的模式匹配 思想 從原串t第乙個位置開始,與s中第乙個位置資料進行匹配,相同則兩個位置均後移,否則,子串退回到第乙個位置,原串t退回到第二個位置,當子串匹配完成,則返回在原串中匹配到的首個位置即可。如...
模式匹配演算法 樸素演算法
1.樸素的模式匹配演算法。樸素模式匹配演算法,簡單的說就是迴圈把主串的每個字元作為開頭,與子串去進行匹配。對主串做大迴圈,每個字元為開頭做子串 要匹配的字串 的小迴圈,如果對應字元匹配,則兩字串都向後移位,否則子串又從子串的開頭開始與主串前一步比較的字元開頭的下一位繼續匹配,直到匹配成功或 主串 遍...
樸素的串模式匹配(C語言實現) 串模式匹配
從主串 s 的第 pos 個字元起和模式 t 的第乙個字元比較之,若相同,則繼續比較後續字元 否則從主串 s 的下乙個字元起再重新和模式 t 的字元比較之。例 s jinanshi t nan 當採用定長順序儲存結構時,實現此操作的演算法如下 int index sstring s,sstring ...