BM 算法包含两部分,分别是坏字符规则(bad character rule)和好后缀规则(good suffix shift)。

1.坏字符规则

按照模式串下标从大到小的顺序,倒着匹配的。
字符串匹配,BM 算法
没有匹配的字符叫作坏字符(主串中的字符)。

拿坏字符 c 在模式串中查找,发现模式串中并不存在这个字符,可以将模式串直接往后滑动三位,再从模式串的末尾字符开始比较。
字符串匹配,BM 算法
这个时候,坏字符 a 在模式串中是存在的,可以将模式串往后滑动两位,让两个 a 上下对齐,然后再从模式串的末尾字符开始,重新匹配。
字符串匹配,BM 算法
滑动规律:当发生不匹配的时候,我们把坏字符对应的模式串中的字符下标记作 si。如果坏字符在模式串中存在,我们把这个坏字符在模式串中的下标记作 xi。如果不存在,我们把 xi 记作 -1。那模式串往后移动的位数就等于 si-xi。(注意,我这里说的下标,都是字符在模式串的下标)。
如果坏字符在模式串里多处出现,那我们在计算 xi 的时候,选择最靠后的那个

BM 算法在最好情况下的时间复杂度非常低,是 O(n/m)。

极端的例子:
主串是 aaaaaaaaaaaaaaaa,模式串是 baaa,移动的位数可能是负数

2.好后缀规则

当模式串滑动到图中的位置的时候,模式串和主串有 2 个字符是匹配的
字符串匹配,BM 算法
把已经匹配的 bc 叫作好后缀,记作{u}。我们拿它在模式串中查找,如果找到了另一个跟{u}相匹配的子串{u*},那我们就将模式串滑动到子串{u*}与主串中{u}对齐的位置。
字符串匹配,BM 算法
如果在模式串中找不到另一个等于{u}的子串,就直接将模式串,滑动到主串中{u}的后面(当模式串滑动到前缀与主串中{u}的后缀有部分重合的时候,移到重合地方)
字符串匹配,BM 算法
字符串匹配,BM 算法

我们可以分别计算好后缀和坏字符往后滑动的位数,然后取两个数中最大的,作为模式串往后滑动的位数。这种处理方法还可以避免我们前面提到的,根据坏字符规则,计算得到的往后滑动的位数,有可能是负数的情况。

好后缀的处理规则中最核心的内容:

  • 在模式串中,查找跟好后缀匹配的另一个子串;
  • 在好后缀的后缀子串中,查找最长的、能跟模式串前缀子串匹配的后缀子串;

BM 算法核心思想是,利用模式串本身的特点,在模式串中某个字符与主串不能匹配的时候,将模式串往后多滑动几位,以此来减少不必要的字符比较,提高匹配的效率。BM 算法构建的规则有两类,坏字符规则和好后缀规则。好后缀规则可以独立于坏字符规则使用。因为坏字符规则的实现比较耗内存,为了节省内存,我们可以只用好后缀规则来实现 BM 算法。

相关文章:

  • 2021-11-22
  • 2021-09-22
  • 2021-10-05
  • 2022-01-16
  • 2021-07-20
  • 2021-06-16
  • 2021-05-10
  • 2022-12-23
猜你喜欢
  • 2022-01-22
  • 2021-11-24
  • 2021-11-20
  • 2022-12-23
  • 2022-12-23
  • 2021-09-04
  • 2021-09-02
相关资源
相似解决方案