比KMP高效的Boyer-Moore字符串匹配算法

       在这里我所要想说的比KMP算法高效的算法是Boyer-Moore算法。

       在讲解Boyer-moore算法之前,在这里先回顾一下KMP算法。

       比如说有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”。大部分情况下我们会使用KMP算法去解:

  1.                           
    《比KMP高效的Boyer-Moore字符串匹配算法》

首先,字符串”BBC ABCDAB ABCDABCDABDE”的第一个字符与搜索词”ABCDABD”的第一个字符,进行比较。因为B与A不匹配,所以搜索词后移一位。
2.
《比KMP高效的Boyer-Moore字符串匹配算法》

B与A不匹配,搜索词向后移一位。直到有一位搜索词相同。
3.
《比KMP高效的Boyer-Moore字符串匹配算法》



可以看到前6个数都是相同的,但是最后一个数D与空格不相同。根据KMP算法,搜索词向后移动一位。但是这就是KMP算法效率低的地方,之前的6个数我们已经比较过了,已经不可能匹配了,但是KMP算法还是重复的匹配。在后面讲的Boyer-Moore算法会有优化。
4.《比KMP高效的Boyer-Moore字符串匹配算法》


     其实KMP在这里是有优化的,KMP算法的想法是,设法利用这个已知信息,不要把”搜索位置”移回已经比较过的位置,继续把它向后移,这样就提高了效率。
    利用《部分匹配表》(Partial Match Table)可以根据公式:
             移动位数 = 已匹配的字符数 – 对应的部分匹配值;
 算出向后移动的位数。




5. 部分匹配表实例:
《比KMP高效的Boyer-Moore字符串匹配算法》

     “部分匹配”的实质是,有时候,字符串头部和尾部会有重复。比如,”ABCDAB”之中有两个”AB”,那么它的”部分匹配值”就是2(”AB”的长度)。搜索词移动的时候,第一个”AB”向后移动4位(字符串长度-部分匹配值),就可以来到第二个”AB”的位置。



Boyer-Moore算法:


坏字符算法:
           其实Boyer-Moore算法使用最多的是大部分软件里的“查找算法”。crtl+F4的功能。
《比KMP高效的Boyer-Moore字符串匹配算法》



注意:Boyer-Moore算法是从后向前匹配的。这是一个很聪明的想法,因为如果尾部字符不匹配,那么只要一次比较,就可以知道前7个字符(整体上)肯定不是要找的结果。


如上面的情况:
Boyer-Moore是怎么处理的呢?

《比KMP高效的Boyer-Moore字符串匹配算法》

我们看到,”C”与”D”不匹配。这时,”C”就被称为”坏字符”(bad character),即不匹配的字符。我们还发现,”C”包含在搜索词”ABCDABD”之中,这意味着可以把搜索词直接移到”C”的后一位。

《比KMP高效的Boyer-Moore字符串匹配算法》

我们看到,”D”与”空格不匹配。这时,空格就被称为”坏字符”(bad character),即不匹配的字符。我们还发现,空格不包含在搜索词”ABCDABD”之中,这意味着可以把搜索词直接移到空格的后一位。

《比KMP高效的Boyer-Moore字符串匹配算法》

而后面的“C”和“D”不相同,但是我们可以注意到坏字符“C”在搜索词“ABCDABD”中,根据规则我们将搜索词中的“C”移动到坏字符处:

《比KMP高效的Boyer-Moore字符串匹配算法》

这样,我们就找到了匹配的字符串了。。

我们可以总结Boyer-Moore的坏字符算法:

后移位数 = 坏字符的位置 – 搜索词中的上一次出现位置

即:坏字符“C”(上面的那一个C)出现在搜索词的第6位(从0开始),在搜索词中上一次出现的位置是2。所以6-2=4。

向后移动4位。

注意:如果”坏字符”不包含在搜索词之中,则上一次出现位置为 -1。


Boyer-Moore算法除了有”坏字符算法“还有

”好后缀算法“:


   那么好后缀算法是什么样的情况呢?这里,我们得换个例子:
   如果出现这种情况:
《比KMP高效的Boyer-Moore字符串匹配算法》

    “MPLE”与”MPLE”匹配。我们把这种情况称为”好后缀”(good suffix),即所有尾部匹配的字符串。注意,”MPLE”、”PLE”、”LE”、”E”都是好后缀。

《比KMP高效的Boyer-Moore字符串匹配算法》

      比较”I”与”A”不匹配,那么”I”就是坏字符。根据”坏字符规则”,此时搜索词应该后移 2 – (-1)= 3 位。但是在这里我们采用“好后缀算法”:
后移位数 = 好后缀的位置 – 搜索词中的上一次出现位置
此时,所有的”好后缀”(MPLE、PLE、LE、E)之中,只有”E”在”EXAMPLE”还出现在头部,所以后移 6 – 0 = 6位。

《比KMP高效的Boyer-Moore字符串匹配算法》



“坏字符规则”只能移3位,”好后缀规则”可以移6位。所以,Boyer-Moore算法的基本思想是,每次后移这两个规则之中的较大值。

《比KMP高效的Boyer-Moore字符串匹配算法》

继续从尾部开始比较,”P”与”E”不匹配,因此”P”是”坏字符”。根据”坏字符规则”,后移 6 – 4 = 2位。

《比KMP高效的Boyer-Moore字符串匹配算法》

匹配完成。。。

     

    原文作者:KMP算法
    原文地址: https://blog.csdn.net/leex_brave/article/details/51853488
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞