字串匹配的KMP演算法

來源:互聯網
上載者:User

標籤:長度   包括   電腦   尾碼   rac   jpg   str   nal   查表   

字串匹配是電腦的基本任務之中的一個。

  舉例來說,有一個字串"BBC ABCDAB ABCDABCDABDE"。我想知道。裡面是否包括還有一個字串"ABCDABD"?

  很多演算法能夠完畢這個任務,Knuth-Morris-Pratt演算法(簡稱KMP)是最經常使用的之中的一個。它以三個發明者命名。起頭的那個K就是著名科學家Donald Knuth。

  這樣的演算法不太easy理解。網上有非常多

q=Knuth-Morris-Pratt+algorithm" target="_blank">解釋。但讀起來都非常費勁。直到讀到Jake Boxer的文章。我才真正理解這樣的演算法。

以下,我用自己的語言,試圖寫一篇比較好懂的KMP演算法解釋。

  1.

  首先,字串"BBC ABCDAB ABCDABCDABDE"的第一個字元與搜尋字詞"ABCDABD"的第一個字元。進行比較。由於B與A不匹配。所以搜尋字詞後移一位。

  2.

  由於B與A不匹配,搜尋字詞再往後移。

  3.

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

  4.

  接著比較字串和搜尋字詞的下一個字元。還是同樣。

  5.

  直到字串有一個字元。與搜尋字詞相應的字元不同樣為止。

  6.

  這時,最自然的反應是,將搜尋字詞整個後移一位,再從頭逐個比較。這樣做儘管可行,可是效率非常差,由於你要把"搜尋位置"移到已經比較過的位置,重比一遍。

  7.

  一個基本事實是,當空格與D不匹配時,你事實上知道前面六個字元是"ABCDAB"。KMP演算法的想法是。設法利用這個已知資訊。不要把"搜尋位置"移回已經比較過的位置,繼續把它向後移。這樣就提高了效率。

  8.

  怎麼做到這一點呢?能夠針對搜尋字詞,算出一張《部分匹配表》(Partial Match Table)。這張表是怎樣產生的,後面再介紹。這裡僅僅要會用就能夠了。

  9.

  已知空格與D不匹配時,前面六個字元"ABCDAB"是匹配的。

查表可知。最後一個匹配字元B相應的"部分匹配值"為2。因此依照以下的公式算出向後移動的位元:

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

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

  10.

  由於空格與C不匹配,搜尋字詞還要繼續往後移。這時,已匹配的字元數為2("AB"),相應的"部分匹配值"為0。所以,移動位元 = 2 - 0,結果為 2。於是將搜尋字詞向後移2位。

  11.

  由於空格與A不匹配,繼續後移一位。

  12.

  逐位比較,直到發現C與D不匹配。於是。移動位元 = 6 - 2,繼續將搜尋字詞向後移動4位。

  13.

  逐位比較,直到搜尋字詞的最後一位,發現全然匹配,於是搜尋完畢。

假設還要繼續搜尋(即找出所有匹配)。移動位元 = 7 - 0,再將搜尋字詞向後移動7位,這裡就不再反覆了。

  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的演算法流程:

  • 如果如今文本串S匹配到 i 位置。模式串P匹配到 j 位置
    • 假設j = -1,或者當前字元匹配成功(即S[i] == P[j]),都令i++,j++,繼續匹配下一個字元。
    • 假設j != -1,且當前字元匹配失敗(即S[i] != P[j])。則令 i 不變。j = next[j]。此舉意味著失配時,模式串P相對於文本串S向右移動了j - next [j] 位。”

    我們發現假設某個字元匹配成功。模式串首字元的位置保持不動,不過i++、j++;假設匹配失配。i 不變(即 i 不回溯),模式串會跳過匹配過的next [j]個字元。整個演算法最壞的情況是,當模式串首字元位於i - j的位置時才匹配成功,演算法結束。
    所以。假設文本串的長度為n。模式串的長度為m。那麼匹配過程的時間複雜度為O(n),算上計算next的O(m)時間。KMP的總體時間複雜度為O(m + n)


很多其它瞭解能夠查看July解說:http://blog.csdn.net/v_july_v/article/details/7041827

字串匹配的KMP演算法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.