Boyer–Moore BM 后缀匹配算法

Boyer–Moore BM 后缀匹配算法,第1张

Boyer–Moore BM 后缀匹配算法 前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

Boyer–Moore

Boyer–Moore算法是一种在O(n)时间复杂度内的字符串匹配算法,简称BM算法,是一种后缀匹配算法,在你计算机使用中随处可见,比如你常使用的ctrl+f

这个算法的核心灵魂是,当每次匹配失败时,将尽可能多的向前位移,而不是逐个进行字符匹配判断,那样还是有点蠢的

在绝大多数场合的性能表现,Boyer–Moore算法比KMP算法还要出色,而KMP算法和BM算法,它们分别是前缀匹配和后缀匹配的经典算法


BM算法在移动模式串的时候是从左到右,而进行比较的时候是从右到左的


比如这样一段文本与一段匹配词

很明显,这是一次失败的匹配,虽然是从开头,一旦触发了失败的匹配,那么BM算法将遵循两种规则进行匹配词的位移判断,尽可能多的跳过不需要匹配的文本

这两种规则,就是人尽皆知的好后缀规则与坏后缀规则


坏后缀

坏后缀的理解非常简单,当匹配到的字符,不与当前位置的文本相符,那么这就是一个坏后缀,比如这里的话

又或者下面这样例子中的e

a b c d e f
a b c e

好后缀

那么好后缀也是相当的简单去理解,当从末尾开始,当前位置的字符与文本相符,那么这就是一个好后缀

比如

a (b) {c d} e f
w (y) {c d}

那么c d就是一个好后缀,而y则是一个坏后缀


理解了好后缀与坏后缀之后,那么接下来欣赏一下BM算法在遇到好后缀与坏后缀时的处理规则

或者坏后缀与好后缀同时遇到时候的规则


坏后缀

如果遇到了一个坏后缀,那么会有如下两种情况

  • 在整个匹配词中,坏后缀对应位置的匹配文本都没有出现,那么将直接跳过这一段匹配文本,从当前坏后缀的下一个位置开始进行重新匹配

比如

a b c {d} e x x x x 
w y z {f}

匹配文本w y z f的坏后缀f对应的d匹配字符,并没有出现在w y z f中,那么这将直接跳过a b c d

也就是将直接从e处继续进行匹配

a b c d e x x x x 
        w y z f
  • 如果坏后缀对应的匹配文本出现在了匹配词前面的位置,那么以该字符进行对齐

按照最一开始的图示,当匹配虽然是一个坏后缀时

但是,我们发现,匹配对应的文本宝出现在了匹配词的第一个位置,那么将位移宝至文本中的宝进行对齐

坏后缀移动规则

稍微品一品坏后缀的两种移动方式,不难得出如下的移动规略

匹配词的移动位数 = 后缀索引 - 坏后缀对应文本在匹配词中出现的索引位置

如果坏后缀对应的文本并未出现在匹配词中,那么此时对应的位置为-1


回顾一下之前的匹配动作,比如

a b c {d} e x x x x 
w y z {f}

那么发现d文本并未出现在匹配词中,那么匹配词将位移

3(坏后缀索引) - -1(未出现在匹配词中) = 4(最终位移结果数量)


再比如出现在匹配词中的情况

a  b  c {d} e x x x x 
w {d} z {f}

那么发现d文本出现在了w d z f中,那么首先可以确定坏后缀对应文本在匹配词中的位置是1(索引从0开始)

得出位移结果

3(坏后缀索引) - 1 = 2, 此时w d z f将向后位移2

a b c {d} e x x x x 
    w {d} z f

好后缀

知道了坏后缀的处理规则,那么再来看一下好后缀的方式,和坏后缀类似,匹配到的好后缀文本是否出现在匹配词中,分为两种情况

  • 当匹配到的文本未出现在之前的匹配词中

比如

a b {c d} e x x x x 
w y {c d}

此时文本中的c d与匹配词的末尾c d匹配,这称的上是一个好后缀,但是c d只在末尾出现,未出现在匹配词其余部位,那么,类似坏后缀的同样规则,这将直接向后跳过整段匹配文本

a b c d e x x x x 
        w y c d
  • 当匹配到的文本出现在了匹配词中
a b c d e x x x x 
d e c d e

d e好后缀出现在了开头起点,那么此时将以这样的好后缀对齐

a b c d e x x x x 
      d e c d e

好后缀位移规则

再来稍微品一品好后缀的两种移动方式,不难得出如下的移动规略

匹配词的移动位数 = 后缀索引 - 坏后缀对应文本在匹配词中出现的索引位置

如果坏后缀对应的文本并未出现在匹配词中,那么此时对应的位置为-1


比如第一种,好后缀对应文本未出现在匹配词中,此时好后缀取最后的索引,也就是3

a b {c d} e x x x x 
w y {c d}

此时,对应坏后缀文本c d未出现在匹配词中,那么将位移

3(好后缀最后索引) - -1(未出现在匹配词中) = 4

结果就是,直接向后移动4

a b c d e x x x x 
        w y c d

第二种,好后缀对应文本出现在了匹配词中

a (b) {c d e} x x x x 
d (e) {c d e}

出现在匹配词中的索引位置为3,那么按照规则,将位移

3(好后缀索引) - 0(出现在匹配词的第一个) = 3

a b c d e x x x x 
      d e c d e

品一品,是不是非常的简单

同时具有好后缀,坏后缀

至此,明白了BM算法,那么还有一种情况需要我们考虑

a (b) {c d e} x 
d (e) {c d e}

这里的好后缀为c d e、坏后缀为b

那么也可以按照好后缀,也可以按照坏后缀的方式进行移动,这又该如何抉择呢?

这就要遵循Boyer-Moore算法的基本思想:每次后移这两个规则之中的较大值


这里的好后缀d e,遵循出现在匹配词的规则

位移数量为3

3(后缀索引) - 0(出现在匹配词的第一个) = 3

a b c d e x 
      d e c d e

而坏后缀的文本b,遵循坏后缀中未出现在匹配词的规则

位移数量为

1(后缀索引) - -1(未出现在匹配词中) = 2

a b c d e x
    d e c d e

结果已经显而易见

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5679904.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存