BoyerMoore 算法分析
创始人
2024-05-22 04:44:46
0

BoyerMoore 算法分析

匹配方向:从右向左开始匹配(从 ^ 的位置开始向左匹配):

aaaaaFaaaaaaaaaaaaaa
aaaaaaa^

一、坏字符匹配

坏字符:源串中第一个不匹配的字符就是坏字符(F 是坏字符):

aaaaaFaaaaaaaaaaaaa
aaaaaaa^

指针移动方式1

如果坏字符不在模式串中,则将指针向右移动“模式串长度”个字符,重新开始比较:

aaaaaFaaaaaFaaaaaaaaaaaaaa-------^

解释:当前模式串为 7 个 a,所以指针向右移动 7 个字符,目的是把 F 排除于下次比较的范围,如果移动不足 7 个字符,那么 F 就进入了下次比较的范围,由于 F 不在模式串中,让它进入比较范围没有意义。

重新比较之后,再次遇到坏字符 F:

aaaaaFaaaaaFaaaaaaaaaaaaaa^

指针继续向右移动 7 个字符:

aaaaaFaaaaaFaaaaaaaaaaaaaa-------^

完成匹配。

指针移动方式2

如果坏字符在模式串中,则需要在开始搜索之前,先找出模式串中各个字符最后出现的位置,然后记下该位置之后还有多少个字符。

aaaaabaaaaabccbcaaa
aabccbc

不看源串,只看模式串:
最右边的 a 之后有 5 个字符
最右边的 b 之后有 1 个字符
最右边的 c 之后有 0 个字符

记录该数据的目的是为了让指针能够跳转指定的长度,但是字符 c 所记录的数据 0 却没有使指针产生移动,所以最后一个字符不应该被记录,这样我们就需要使用前一个 c 的位置来记录,也就是 c 之后有 2 个字符,于是有了下面的跳转表:

如果遇到坏字符 a,则指针向右移动 5 个字符
如果遇到坏字符 b,则指针向右移动 1 个字符
如果遇到坏字符 c,则指针向右移动 2 个字符
如果遇到其它坏字符,则指针向右移动“模式串长度”个字符

开始比较:

aaaaabaaaaabccbcaaa
aabccbc^

遇到坏字符 a,指针向右移动 5 个字符:

aaaaabaaaaabccbcaaaaabccbc-----^

解释:跳转表中记录的遇到 a 应该跳转 5 个字符,目的是为了让源串中的坏字符 a 与模式串中的字符 a 对齐,如果跳转不足 5 个字符,则模式串中没有任何字符可以与源串中的 a 匹配上,因为 5 就是 a 在模式串中最后一次出现的位置,再往后就没有 a 了。

重新比较之后,再次遇到坏字符 b:

aaaaabaaaaabccbcaaaaabccbc^

根据跳转表中的记录,遇到 b 应该使指针向右移动 1 个字符:

aaaaabaaaaabccbcaaaaabccbc-^

重新比较之后,再次遇到坏字符 a:

aaaaabaaaaabccbcaaaaabccbc^

指针向右移动 5 个字符:

aaaaabaaaaabccbcaaaaabccbc-----^

完成匹配。

前面提到的跳转表,叫做“坏字符跳转表”,使用该表已经可以实现字符串快速查找。

二、好后缀匹配

为了进一步提高速度,BoyerMoore 算法还提出了另一种匹配方式,叫做“好后缀”匹配。

好后缀:匹配过程中已经匹配的部分就是好后缀(ba 是好后缀):

aaFbaaaaaba
aaaba^

指针移动方式1

如果好后缀在模式串中没有重复的部分(比如 ababa 中后缀 ba 就与前一个 ba 重复,这就不符合当前的情况),则将指针向右移动“模式串长度+已匹配长度”个字符,重新开始比较:

aaFbaaaaaba
-----aaaba-------^

说明:模式串刚好移动到源串上次匹配的 ba 之后,因为模式串向右移动的原则是“使源串中上次匹配的 ba 与模式串中离好后缀 ba 最近的某个 ba 对齐”,可是好后缀左边没有重复的 ba,所以无法与源串中的 ba 对齐,那就只能将模式串整个移动到源串的 ba 之后。

重新比较之后,没有出现好后缀:

aaFbaaaaabaaaaba^

只能向右移动一个字符:

aaFbaaaaaba-aaaba-^

完成匹配。

指针移动方式2

如果好后缀在模式串中有重复的部分,则将指针向右移动“好后缀到最后一个重复部分之间的距离+已匹配的长度”个字符,重新开始比较:

aaaaaaFbabaCbaCba
abaCbaCba^

因为好后缀 ba 前面有重复的 ba,所以需要将离好后缀最近的 ba 与源串中上次匹配的 ba 对齐:

aaaaaaFbabaCbaCba
---abaCbaCba-----^

此时没有匹配的后缀,只能将模式串向右移动一个字符:

aaaaaaFbabaCbaCba-abaCbaCba-^

此时仍然没有匹配的后缀,只能将模式串向右移动一个字符:

aaaaaaFbabaCbaCba-abaCbaCba-^

此时出现好后缀 baCba:

aaaaaaFbabaCbaCbaabaCbaCba^

这个好后缀比较特殊,它是有重复部分的,只不过前后重叠在一起:

aaaaaaFbabaCbaCbaabaCbaCba^^^^^^^^^^^

此时需要将重复部分移动到源串中上次匹配的 baCba 位置:

aaaaaaFbabaCbaCba---abaCbaCba--------^

完成匹配。

如果有多个连续的重复部分,则可以一次跳过所有这些重复部分,例如:

aaaaaaaFbababababa
bababababa^

按照一般思路,应该将离好后缀最近的一个 ba 与源串中上次匹配的 ba 对齐,但是因为这些重复 ba 是相连的,既然 F 与好后缀 ba 之前的 a 不匹配,那么所有相连的 ba 前一个字符都是 a,都不可能与 F 匹配,所以可以一次跳过所有相连的 ba,将最左边的重复 ba 与源串中上次匹配的 ba 对齐即可:

aaaaaaaFbababababa
--------bababababa---------^

完成匹配。

好后缀也有一个跳转表,只需要在搜索之前计算好,就可以实现快速搜索,好后缀的跳转表计算起来要比坏字符复杂一些。

BoyerMoore 算法同时使用“坏字符”和“好后缀”两种跳转方式,每次遇到坏字符时,也会出现好后缀,然后选择两种跳转方式中跳转距离更远的作为本次跳转长度。

在 FPC 的 StrUtils 单元中有 BoyerMoore 算法的实现,可以参考。

相关内容

热门资讯

最新!印巴将再次会谈!巴基斯坦... 每经编辑|毕陆名 据央视新闻11日消息,当地时间5月10日,巴基斯坦总理夏巴兹·谢...
兰州市城关区前街社区:三大突破... 前街社区:三大突破助力打造防灾“样板间”  5月8日,城关区伏龙坪街道前街社区联合街道办事处、社区卫...
李家超率团抵达多哈展开访问行程... 经济观察网讯 据大湾区之声消息,5月11日,香港特区行政长李家超率领香港商贸代表和内地企业代表抵达多...
五一文旅成绩单喜人,金融一揽子... 转自:上观新闻5月6日至11日,“2025现代汽车·射箭世界杯赛-陆家嘴金融城上海站”在浦东新区火热...
17场精彩大戏正在上海上演! 作者:朱伟微信编辑:安通
小城荣昌,凭借一只鹅走红的背后 丨“这座城市有点东西”城市是经济活动的中心,是高质量发展的重要推动力,是经济中最具活力的因素。中新社...
燃情省城市足球联赛! 镇江队3... 转自:扬子晚报扬子晚报网5月11日讯(通讯员 周婷婷 顾学谦 记者 万凌云) 5月10日下午3时,随...
书香花语・与爱同行!南京鼓楼西... 母亲节是一个充满爱与温情的日子。5月10日,南京市鼓楼区凤凰街道西城岚湾社区依托 “阅岚湾——行走课...
马鞍山市原副市长黄化锋一审获刑... 近日,安徽省六安市中级人民法院对马鞍山市委原常委、市政府原党组副书记、副市长黄化锋犯受贿罪一案作出一...
锐评|为发论文窃取机密?卖国求... 转自:北京日报客户端为发外刊论文,竟安排学生实习窃密?11日,国家安全部披露一起偷贩涉密敏感数据案,...
英特尔确认终止 Deep Li... IT之家 5 月 11 日消息,英特尔确认 Alchemist 曾经的卖点之一 Deep Link ...
2025南师校友天团|南京市金... 转自:扬子晚报@高考生,你家书记校长喊你上南师啦!5月8日起,南京师范大学本科招生办公室联合扬子晚报...
联动巡视期间,董志向官宣落马 武汉市纪委监委5月10日晚消息,武汉旅游体育集团有限公司原党委书记、董事长董志向涉嫌严重违纪违法,目...
事关固态电池!下周多场技术大会...   下周,电池行业即将召开多场技术大会。  第十七届深圳国际电池技术交流会/博览会(CIBF2025...
快自查!这些App被通报 近日中央网信办发布关于15款App和16款SDK个人信息收集使用问题的通报墨迹天气tv版、企鹅天气和...
直击零售业博览会,实探支付科技... 南方财经全媒体记者 黄子潇 深圳报道支付公司推销充电宝、“哪吒敖丙”空降展台、现场搭建便利店.......
传习录丨勿忘人间真情 来源:央视新闻客户端 01:06“慈母手中线,游子身上衣...
房山第一书记喊你赶集啦…… 为进一步拓宽农产品销售渠道,更好宣传房山文旅资源,近日,在区委组织部、青龙湖镇党委的大力协调下,驻村...
海南临高县遇强风仓库被掀顶 转自:新京报我们视频 【#海南临高县遇强风仓库被掀顶#】...
在网红打卡点挖萤石,杭州9岁男... 本文来自微信公众号“大象新闻”5月10日下午1点30分左右,杭州消防接到报警:余杭四岭村千岱坑萤石矿...