kmp的匹配是從模式串的開頭開始匹配的,而2023年,德克薩斯大學的robert s. boyer教授和j strother moore教授發明了一種新的字串匹配演算法:boyer-moore演算法,簡稱bm演算法。該演算法從模式串的尾部開始匹配,且擁有在最壞情況下o(n)的時間複雜度。在實踐中,比kmp演算法的實際效能高。
bm演算法定義了兩個規則:
下面舉例說明bm演算法。例如,給定文字串「here is a ****** example」,和模式串「example」,現要查詢模式串是否在文字串中,如果存在,返回模式串在文字串中的位置。
1. 首先,"文字串"與"模式串"頭部對齊,從尾部開始比較。"s"與"e"不匹配。這時,"s"就被稱為"壞字元"(bad character),即不匹配的字元,它對應著模式串的第6位。且"s"不包含在模式串"example"之中(相當於最右出現位置是-1),這意味著可以把模式串後移6-(-1)=7位,從而直接移到"s"的後一位。
. 依然從尾部開始比較,發現"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位。每次後移這兩個規則之中的較大值。這兩個規則的移動位數,只與模式串有關,與原文本串無關。
. 繼續從尾部開始比較,「p」與「e」不匹配,因此「p」是「壞字元」,根據「壞字元規則」,後移 6 - 4 = 2位。因為是最後一位就失配,尚未獲得好字尾。
由上可知,bm演算法不僅效率高,而且構思巧妙,容易理解。
演算法 BM演算法
如果要判定長度為n nn兩個字串相等,比較中要進行n nn比較,但是如果要判定兩個字串不相等,只需要找出乙個不相等的位置,因此可以得到如下結論 結論1 判定字串相等和判定字串不相等的代價不同,判定不相等的代價更小 在kmp演算法中,每發生一次失配時,演算法總是嘗試根據已經獲得的匹配成功的資訊來確定乙...
BM演算法詳解
bm演算法 字尾匹配,是指模式串的比較從右到左,模式串的移動也是從左到右的匹配過程,經典的bm演算法其實是對字尾蠻力匹配演算法的改進。為了實現更快移動模式串,bm演算法定義了兩個規則,好字尾規則和壞字元規則,如下圖可以清晰的看出他們的含義。利用好字尾和壞字元可以大大加快模式串的移動距離,不是簡單的 ...
BM演算法總結
bm演算法,可以求乙個數列的最短遞推式。採用增量法,依次考慮每個數 若在這個位置上正確,則忽略 否則,類似拉格朗日插值法,找乙個滿足在前面位置都為0,這個位置上不為0的遞推式,進行修補。每當我們遇到乙個這樣的位置時,我們都可以得到乙個這樣的遞推式 用目前的遞推式,在0位置 即這個位置上 增加乙個 1...