字串匹配與KMP演算法實現

2021-09-23 21:47:59 字數 2089 閱讀 9008

字串匹配問題

字串匹配問題即在匹配串中尋找模式串是否出現,

首先想到的是使用暴力破解,也就是brute force(bf或蠻力搜尋) 演算法,將匹配串和模式串左對齊,然後從左向右乙個乙個進行比較,

如果不成功則模式串向右移動乙個單位,直到匹配成功或者到達匹配串最後仍然不成功,返回失敗。

很明顯,這種演算法有很多的地方可以優化,假設要搜尋的串為s,長度為n,要匹配的串為m,長度為m,時間複雜度為o(nm)。

(1)boyer-moore演算法

(2)rabin-karp演算法

knuth-morris-pratt演算法以三個發明者命名,knuth就是著名科學家donald knuth,鼎鼎大名, ( 簡稱taocp)的作者。

kmp演算法不太容易理解和實現,下面這段來自阮一峰的網路日誌,對kmp的介紹比較簡潔易懂,摘錄下來,有時間再記錄一下自己的理解和演算法的實現。

這種演算法不太容易理解,網上有很多解釋,但讀起來都很費勁。直到讀到jake boxer的文章,我才真正理解這種演算法。下面,我用自己的語言,試圖寫一篇比較好懂的kmp演算法解釋。

1.首先,字串"bbc abcdab abcdabcdabde"的第乙個字元與搜尋詞"abcdabd"的第乙個字元,進行比較。因為b與a不匹配,所以搜尋詞後移一位。

2.因為b與a不匹配,搜尋詞再往後移。

3.就這樣,直到字串有乙個字元,與搜尋詞的第乙個字元相同為止。

4.接著比較字串和搜尋詞的下乙個字元,還是相同。

5.直到字串有乙個字元,與搜尋詞對應的字元不相同為止。

6.這時,最自然的反應是,將搜尋詞整個後移一位,再從頭逐個比較。這樣做雖然可行,但是效率很差,因為你要把"搜尋位置"移到已經比較過的位置,重比一遍。

7.8.

怎麼做到這一點呢?可以針對搜尋詞,算出一張《部分匹配表》(partial match table)。這張表是如何產生的,後面再介紹,這裡只要會用就可以了。

9.已知空格與d不匹配時,前面六個字元"abcdab"是匹配的。查表可知,最後乙個匹配字元b對應的"部分匹配值"為2,因此按照下面的公式算出向後移動的位數:

移動位數 = 已匹配的字元數 - 對應的部分匹配值

因為 6 - 2 等於4,所以將搜尋詞向後移動4位。

10.11.

因為空格與a不匹配,繼續後移一位。

12.逐位比較,直到發現c與d不匹配。於是,移動位數 = 6 - 2,繼續將搜尋詞向後移動4位。

13.14.

下面介紹《部分匹配表》是如何產生的。

首先,要了解兩個概念:"字首"和"字尾"。 "字首"指除了最後乙個字元以外,乙個字串的全部頭部組合;"字尾"指除了第乙個字元以外,乙個字串的全部尾部組合。

15."部分匹配值"就是"字首"和"字尾"的最長的共有元素的長度。以"abcdabd"為例,

- "a"的字首和字尾都為空集,共有元素的長度為0;

- "ab"的字首為[a],字尾為[b],共有元素的長度為0;

- "abc"的字首為[a, ab],字尾為[bc, c],共有元素的長度0;

- "abcd"的字首為[a, ab, abc],字尾為[bcd, cd, d],共有元素的長度為0;

- "abcda"的字首為[a, ab, abc, abcd],字尾為[bcda, cda, da, a],共有元素為"a",長度為1;

- "abcdab"的字首為[a, ab, abc, abcd, abcda],字尾為[bcdab, cdab, dab, ab, b],共有元素為"ab",長度為2;

- "abcdabd"的字首為[a, ab, abc, abcd, abcda, abcdab],字尾為[bcdabd, cdabd, dabd, abd, bd, d],共有元素的長度為0。

16.

"部分匹配"的實質是,有時候,字串頭部和尾部會有重複。比如,"abcdab"之中有兩個"ab",那麼它的"部分匹配值"就是2("ab"的長度)。搜尋詞移動的時候,第乙個"ab"向後移動4位(字串長度-部分匹配值),就可以來到第二個"ab"的位置。

字串匹配與KMP演算法

參考 j.boxer s blog the knuth morris pratt algorithm in my own words.在電腦科學中,knuth morris pratt字串查詢演算法 簡稱為kmp演算法 可在乙個主文字字串 s 內查詢乙個詞 w 的出現位置。此演算法通過運用對這個詞在...

字串匹配的KMP演算法實現

問題源自資料結構書。問題 字串src中含有模式串pat的個數 舉例 src 00000111111111101010111010101001 pat 110 src中含有多少個pat?分析 沒有回溯的kmp演算法。1 首先實現乙個next數字,其中的值,是匹配失誤之後的下一次匹配的位置。next 0...

用KMP演算法實現字串匹配

如果對於乙個字串a,將a的前面任意一部分挪到後邊去形成的字串稱為a的旋轉詞。比如a 12345 a的旋轉詞有12345,23456,34512,45123和51234。對於兩個字串a和b,請判斷a和b是否互為旋轉詞。給定兩個字串a和b及他們的長度lena,lenb,請返回乙個bool值,代表他們是否...