kmp演算法詳解
模式匹配的經典應用:從乙個字串中找到模式字串的位置。如「abcdef」中「cde」出現在原串第三個位置。從基礎看起
樸素的模式匹配演算法
a:abcdefg b:cde
首先b從a的第一位開始比較,b++==a++,如果全部成立,返回即可;如果不成立,跳出,從a的第二位開始比較,以此類推。
思路樸實無華,十分有效,但是時間複雜度是o(mn),m、n分別是字串和模式串的長度。模式匹配是乙個常見的應用問題,用的廣了,就有人想法去優化了。rabin-karp演算法、有限自動機等等,前仆後繼,最終出現了kmp(knuth-morris-pratt)演算法。
kmp演算法
優化的地方:如果我們知道模式中a和後面的是不相等的,那麼第一次比較後,發現後面的的4個字元均對應相等,可見a下次匹配的位置可以直接定位到f了。說明主串對應位置i的回溯是不必要的。這是kmp最基本最關鍵的思想和目標。
再比如:
由於abc 與後面的abc相等,可以直接得到紅色的部分。而且根據前一次比較的結果,abc就不需要比較了,現在只需從f-a處開始比較即可。說明主串對應位置i的回溯是不必要的。要變化的是模式串中j的位置(j不一定是從1開始的,比如第二個例子)
j的變化取決於模式串的前字尾的相似度,例2中abc和abc(靠近x的),字首為abc,j=4開始執行。
j是前一次執行的模式子串(前幾個,上例為6)中字首的個數+1;它與模式字串中從前向後的字首和從後向前的字尾的相同子串是有關係的,因為下次這部分相同的字首就會移動到這部分字尾的位置,因為如果移動到字尾的前面位置,看圖:
所以如果這次是j,下次的位置應該就是j前面的子串的最大字首的長度+1,用這個新的位置再和原字串的i位置進行比較就很幸福了。
這次是j,下次到底是多少呢,這就涉及到怎麼計算的問題了?其實只看模式串我們就可以構建出這個j->x的關係,關係稱為字首函式,結果儲存在陣列中,稱為字首陣列。
偽**:
使用字首陣列可很快地實現模式匹配,程式匹配字串中模式出現的所有位置。
這兩段**思想完全相同,如果和字首不同就比較字首的字首…,比較巧妙。如果kmp有難理解的地方,估計就是這段偽碼的了。
kmp演算法的時間複雜度為o(n+m)。
KMP演算法詳解
模式匹配的kmp演算法詳解 這種由d.e.knuth,j.h.morris和v.r.pratt同時發現的改進的模式匹配演算法簡稱為kmp演算法。大概學過資訊學的都知道,是個比較難理解的演算法,今天特把它搞個徹徹底底明明白白。注意到這是乙個改進的演算法,所以有必要把原來的模式匹配演算法拿出來,其實理解...
KMP演算法詳解
kmp演算法即knuth morris pratt演算法,是模式匹配的一種改進演算法,因為是名字中三人同時發現的,所以稱為kmp演算法。因為偶然接觸到有關kmp的問題,所以上網查了一下next陣列和 nextval陣列的求法,卻沒有找到,只有在csdn的資料檔案裡找到了next陣列的簡單求法 根據書...
KMP演算法詳解
相信很多人 包括自己 初識kmp演算法的時候始終是丈二和尚摸不著頭腦,要麼完全不知所云,要麼看不懂書上的解釋,要麼自己覺得好像心裡了解kmp演算法的意思,卻說不出個究竟,所謂知其然不知其所以然是也。經過七八個小時地仔細研究,終於感覺自己能說出其所以然了,又覺得資料結構書上寫得過於簡潔,不易於初學者接...