字串匹配演算法 KMP演算法簡單解釋

2021-08-09 17:14:16 字數 2071 閱讀 8530

kmp演算法是一種改進的字串匹配演算法,由d.e.knuth,j.h.morris和v.r.pratt同時發現,因此人們稱它為克努特——莫里斯——普拉特操作(簡稱kmp演算法)。kmp演算法的關鍵是利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現乙個next()函式,函式本身包含了模式串的區域性匹配資訊。時間複雜度o(m+n)。

這種演算法在網上看了很多解釋,大部分都比較晦澀複雜,直到看到了一篇文章才是真的簡單易懂,包教包會,這裡就按照自己的理解寫一篇文章。

我們用乙個例子來看,在字串「wwe qwerqw qwerqwerqwrt」中查詢是否含有另乙個字串「qwerqwr」。通常做法是將兩個字串進行乙個個比對,當發現乙個字元一致時,進行第二個字元的比對,如果發現不一致,再退回去從首字元的下乙個開始進行新一輪比對,空口說不太好理解,下面我們結合圖來看kmp演算法是如何利用普通匹配失敗的資訊加快效率的。

我們先將兩個字串的第乙個字元進行比對,因為w和q不匹配,因此跳到下個字元開始匹配。

第二位的字元也不匹配,繼續後移

依次比對,直到發現第乙個字元相同的情況

然後接著從第二個字元開始對應比對,直到有乙個字元與搜尋詞對應不相同為止

5. 這時,樸素的對比方法是將搜尋詞後移一位,再從頭逐個比對,例如:

這種方法當然是可行的,但是就體現不出演算法的高效了。

6. 而在kmp演算法中,當我們知道空格和」r」不匹配時,我就相當於知道了它的前面六個字元是」qwerqw」,kmp演算法中需要設法利用這個已知了的資訊,讓搜尋位置後移提供效率。這裡我們用到了一張表,叫做「部分匹配表」,後面我們會再說如何計算出這張表,這裡我們只說如何使用。

搜尋詞qwe

rqwr

部分匹配值00

0012

0接下來說一下部分匹配表是如何生成的。首先,要了解兩個概念:」字首」和」字尾」。 「字首」指除了最後乙個字元以外,乙個字串的全部頭部組合;」字尾」指除了第乙個字元以外,乙個字串的全部尾部組合。

例如:單詞level的字首有四個,字尾有四個,然後字首和字尾集合取交集,得到,只有乙個元素,長度為1,因此level的部分匹配值就是1。

搜尋詞qwe

rqwr

部分匹配值00

0012

0 再回來看上面的字串例子:

「q」的字首和字尾都為空集,共有元素的長度為0;

「qw」的字首為[q],字尾為[w],共有元素的長度為0;

「qwe」的字首為[q, qw],字尾為[we, e],共有元素的長度0;

「qwer」的字首為[q, qw, qwe],字尾為[wer, er, r],共有元素的長度為0;

「qwerq」的字首為[q, qw, qwe, qwer],字尾為[werq, erq, rq, q],共有元素為」q」,長度為1;

「qwerqw」的字首為[q, qw, qwe, qwer, qwerq],字尾為[werqw, erqw, rqw, qw, w],共有元素為」qw」,長度為2;

「qwerqwr」的字首為[q, qw, qwe, qwer, qwerq, qwerqw],字尾為[werqwr, erqwr, rqwr, qwr, wr, r],共有元素的長度為0。

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

字串匹配演算法 KMP演算法

kmp演算法是一種改進的字串匹配演算法。kmp演算法的關鍵是利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現乙個next 函式,函式本身包含了模式串的區域性匹配資訊。下面從乙個例子來了解kmp演算法 字串 bbc abcdab abcdabcdabde 我想...

字串匹配演算法KMP演算法

資料結構中講到關於字串匹配演算法時,提到樸素匹配演算法,和kmp匹配演算法。樸素匹配演算法就是簡單的乙個乙個匹配字元,如果遇到不匹配字元那麼就在源字串中迭代下乙個位置乙個乙個的匹配,這樣計算起來會有很多多餘的不符合的匹配做了冗餘的比較。假設源字串長n,字串長m 該演算法最差時間複雜度為 m n m ...

字串匹配演算法(KMP演算法)

力扣 實現 strstr 函式。給定乙個 haystack 字串和乙個 needle 字串,在 haystack 字串中找出 needle 字串出現的第乙個位置 從0開始 如果不存在,則返回 1。int strstr char haystack,char needle else if j n len...