樸素的模式匹配和改進的模式匹配(KMP)算法說明


樸素的模式匹配和改進的模式匹配(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的簡單介紹,有機會會整理出詳細算法及其優勢!
其他不想多說,只想說明“算法是程序的靈魂!”這一古老而經典的話!!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章