1. 程式人生 > >有關串的模式匹配問題中的kmp演算法(俗稱 看毛片演算法)

有關串的模式匹配問題中的kmp演算法(俗稱 看毛片演算法)

========前言======

最近準備考研,於是重新拾起資料結構這本書(嚴老師的) 對於之前的看毛片演算法想用自己的方式重新總結一下


========沒有這方面基礎的先看 這個網址

     (該網址為百度百科 本人只分享跟連結 若有其他影響本人概不負責)   https://baike.baidu.com/item/kmp%E7%AE%97%E6%B3%95/10951804?fr=aladdin

========BUT=======

演算法的學習主要是看個人自己的理解與抽想 ,我的理解可能大家覺得比較難以理解,沒事,千人千面,歡迎大家在下面補撐自己的看法

===========KMP=======

KMP裡面最主要的就是理解為什麼要將模式串進行最長字首與最長字尾的查詢(或者是為什麼要去求一個(next[]陣列))

1.在之前的暴力匹配中 會有主串的指標回溯 就是指主串會從上一次比較的字元的下一個字元再與模式串的第一個字元比較,以此類推,會有很多不必要的比較(明知道會匹配失敗)--------原因是沒有引入最長字首最長字尾之前,我們只是一味的將模式串的前幾個字元與指標不斷回溯的主串的字串進行比較,在遇見匹配成功之前總會有可能匹配失敗   就像是我們不去了解自己女朋友(模式串)一樣,一味的拿她去比較(是不是很多直男的心聲 雖然木有女朋友 呸) 總會出錯。

於是重點來嘞!

我們應該先挖掘女朋友的特點(模式串的特點) 讓匹配時少走彎路 

例如 主串  abcfgabcdabcfgabcbfd

     模式串 abcfgabcb

其中如上所示 標藍的是匹配成功的 而綠色就是所謂的最長前後綴

我們的女朋友在b(標黑的地方)匹配失敗 !

之前暴力匹配時 會從主串的第二個字元開始(假設一開始從主串第一個開始比較,黑色時怕匹配失敗)

會有很多不必要的比較 

因為我們引入最長前後綴可以看出 主串第二個位置到第四個位置沒有匹配上的(abc)這就增加了很多不必要的比較、

那麼明知會失敗 我們為什麼不去避免這些?

=======kmp登場========

引入最長前後綴之後 我們可以知道 當匹配失敗時 我們應該將模式串向右移動一定長度 減少不必要的匹配(明知道肯定會失敗的匹配) 


    模式串 abcfgabcb 移動多少個合適??答案是 移動 abcfgabc .length()-abc.length()

   此時字首移動到字尾  

  那麼有人會問有沒有可能移動 小於 abcfgabc .length()-abc.length()個位置就能匹配上?也就是說移動過程中會不會漏掉能夠成功的串? 答案是 不會的!!

我們引入最長前後綴後 會有新的條件產生 

新的條件:模式串標記綠色的部分 在主串已匹配過的子串中能夠找到 我們現在應該考慮的是怎樣讓模式串前後綴重逢(或者是讓模式串的字首與主串中已經匹配串的字尾重逢)只要讓他們重逢就能省去不必要的匹配    像上述模式串需要移動8-3=5個位置 有沒有一個可能移動小於五個就重逢(模式串移動小於5個位置的時候會不會遇到跟字首一樣的子串)?

我們用數學的假設思想:

1 假設移動兩個遇見了

那麼此時 如圖:

   

還是符合公式 也就是說你所謂的會在移動中碰見 並不會出現在該串中 而會出現在別的型別的特定模式串(特定的最長前後綴長度)中,但該特定模式串還是會遵循這個公式。

總結也就是 說   你找到的最長前後綴是唯一的 他們只能在模式串中僅有一處碰到 最長字首只能碰到最長字尾!!!!!!

所以 不要在這個問題上耗費時間啦 同基們!!!!