經典的BM算法

KMP的匹配是從模式串的開頭開始匹配的,而1977年,德克薩斯大學的Robert S. Boyer教授和J Strother Moore教授發明了一種新的字符串匹配算法:Boyer-Moore算法,簡稱BM算法。該算法從模式串的尾部開始匹配,且擁有在最壞情況下O(N)的時間複雜度。在實踐中,比KMP算法的實際效能高。

    BM算法定義了兩個規則:

  • 壞字符規則:當文本串中的某個字符跟模式串的某個字符不匹配時,我們稱文本串中的這個失配字符爲壞字符,此時模式串需要向右移動,移動的位數 = 壞字符在模式串中的位置 - 壞字符在模式串中最右出現的位置。此外,如果"壞字符"不包含在模式串之中,則最右出現位置爲-1。
  • 好後綴規則:當字符失配時,後移位數 = 好後綴在模式串中的位置 - 好後綴在模式串上一次出現的位置,且如果好後綴在模式串中沒有再次出現,則爲-1。

    下面舉例說明BM算法。例如,給定文本串“HERE IS A SIMPLE EXAMPLE”,和模式串“EXAMPLE”,現要查找模式串是否在文本串中,如果存在,返回模式串在文本串中的位置。

    1. 首先,"文本串"與"模式串"頭部對齊,從尾部開始比較。"S"與"E"不匹配。這時,"S"就被稱爲"壞字符"(bad character),即不匹配的字符,它對應着模式串的第6位。且"S"不包含在模式串"EXAMPLE"之中(相當於最右出現位置是-1),這意味着可以把模式串後移6-(-1)=7位,從而直接移到"S"的後一位。


    2. 依然從尾部開始比較,發現"P"與"E"不匹配,所以"P"是"壞字符"。但是,"P"包含在模式串"EXAMPLE"之中。因爲“P”這個“壞字符”對應着模式串的第6位(從0開始編號),且在模式串中的最右出現位置爲4,所以,將模式串後移6-4=2位,兩個"P"對齊。


    3. 依次比較,得到 “MPLE”匹配,稱爲"好後綴"(good suffix),即所有尾部匹配的字符串。注意,"MPLE"、"PLE"、"LE"、"E"都是好後綴。

    4. 發現“I”與“A”不匹配:“I”是壞字符。如果是根據壞字符規則,此時模式串應該後移2-(-1)=3位。問題是,有沒有更優的移法?

    5. 更優的移法是利用好後綴規則:當字符失配時,後移位數 = 好後綴在模式串中的位置 - 好後綴在模式串中上一次出現的位置,且如果好後綴在模式串中沒有再次出現,則爲-1。
    所有的“好後綴”(MPLE、PLE、LE、E)之中,只有“E”在“EXAMPLE”的頭部出現,所以後移6-0=6位。
    可以看出,“壞字符規則”只能移3位,“好後綴規則”可以移6位。每次後移這兩個規則之中的較大值。這兩個規則的移動位數,只與模式串有關,與原文本串無關。

    6. 繼續從尾部開始比較,“P”與“E”不匹配,因此“P”是“壞字符”,根據“壞字符規則”,後移 6 - 4 = 2位。因爲是最後一位就失配,尚未獲得好後綴。

    由上可知,BM算法不僅效率高,而且構思巧妙,容易理解。
發佈了12 篇原創文章 · 獲贊 21 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章