大量的数据做字符串匹配_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法...
前言
文章的一开头,还是要强调下字符串匹配的思路
- 将
模式串
和主串
进行比较
- 从前往后比较
- 从后往前比较
2. 匹配时,比较主串
和模式串
的下一个位置
3. 失配时,
- 在
模式串
中寻找一个合适的位置- 如果找到,从这个位置开始与
主串
当前失配位置进行比较 - 如果未找到,从
模式串
的头部与主串
失配位置的下一个位置进行比较
- 如果找到,从这个位置开始与
- 在
主串
中找到一个合适的位置,重新与模式串
进行比较
前面的 BF
和 KMP
算法,都是属于规规矩矩从前向后的操作,后者仅在寻找模式串
的合适位置上进行了优化,而 BM
算法的操作就显得骚了很多,它的优化点在于: 1. 从后往前比较 2. 失配时,寻找的是主串
中合适的位置
算法介绍与分析
关于算法的介绍和分析,网上有很多解释,这里推荐一下阮一峰的字符串匹配的Boyer-Moore算法,很清楚的讲解了整个优化的思路,可以先看完理解了再往下看,因为下面主要介绍一下坏字符规则
和好后缀规则
需要的数据结构的手工求法以及代码实现。
坏字符规则
运用坏字符规则,在算法里主要体现在生成一张散列表,表的key值是字符集里每个字符的ASCII码值,value值是模式串中该字符的位置,举个栗子:
假设字符串的字符集不是很大,用长度为256
的数组来存储,并且初值赋值为-1
。数组的下标对应字符的 ASCII
码值,数组中存储这个字符在模式串中出现的位置。这里要特别说明一点,如果坏字符在模式串里多处出现,选择最靠后的那个,因为这样不会让模式串滑动过多,导致本来可能匹配的情况被滑动略过。
好后缀规则
好后缀规则体现在如何求出 suffix
和 prefix
两个数组以及移动规则
。
suffix 数组
key值表示的是后缀子串的长度,value值表示的是在模式串
中跟好后缀 S 相匹配的最后一个子串 S' 的首字母在模式串
中的key值,如下图:
prefix 数组
同样的,key值表示的是后缀子串的长度,而value值表示的是模式串
中,是否有和该长度下后缀子串相同的前缀子串,是的话为 true
,否则为 false
,如下图:
移动规则
移动规则总结如下
- 在
模式串
中寻找跟好后缀 S 相匹配的最后一个子串 S' - 如果找到,将
模式串
移动到使得 S' 和主串
对齐的位置 - 如果找不到,再寻找
模式串
的前缀子串
中是否有和好后缀 S
的后缀子串
匹配的位置,滑动模式串
以对齐。 - 如果仍然找不到,则将
模式串
移动至主串
与模式串
末尾对齐的下一个位置
下图分别对应三种情况:
代码实现
整体逻辑框架
参考字符串匹配的思路
- 仍然需要进行
主串
和模式串
的字符对比,所以需要两个指针i
,j
分别指向主串
和模式串
,记录位置 需要一个循环来重复进行匹配操作,此时思考终止条件:i
指向主串
每次匹配的合适位置,从前往后扫描;j
指向模式串
的尾部,从后往前扫描。考虑极端情况:主串
和模式串
对比完,仍然无法匹配。此时,i
的位置一定小于等于主串
长度n
与模式串
长度m
的差值。具体可看下图。
- 每次
模式串
从后往前与主串
进行匹配,这也需要一个内层循环来驱动指针j
如果匹配,只需要继续移动匹配位置即可 - 如果失配,分别根据
坏字符规则
和好后缀规则
计算出i
需要移动的位置,选择两个值当中最大的,重新计算i
的值,重复进行匹配。
根据以上分析可以写出整个的逻辑框架代码:
框架写好后,接下来就是完善三个辅助函数即可
求坏字符散列表
这个就没有什么可以多说的了,只要参考上面分析的,一步一步写出代即可:
求好后缀记录数组 suffix
和 prefix
拿下标从 0
到 i
的子串(i
可以是 0
到 m-2
)与整个模式串,求公共后缀子串。如果公共后缀子串的长度是 k
,那就记录 suffix[k]=j
(j
表示公共后缀子串的起始下标)。如果 j 等于 0
,也就是说,公共后缀子串也是模式串的前缀子串,就记录 prefix[k]=true
。可以自己动下手,模拟下代码的运行,尤其注意中k
值的运用,很巧妙。
求好后缀移动步数
根据上面此步的算法分析,也可以写出:
总结
总的来说,BM算法
另辟蹊径,通过从后往前的匹配的思路,加上坏字符规则和好后缀规则来优化移动的步数,从而提高算法的匹配效率。
后记
“字符串匹配算法”是“重学数据结构与算法”系列笔记:
- 字符串匹配算法(一)——BF算法
- 字符串匹配算法(二)——KMP算法
- 字符串匹配算法(三)——BM算法
- 字符串匹配算法(四)——Sunday算法
大量的数据做字符串匹配_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法...相关推荐
- diff算法阮一峰_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法
前言 文章的一开头,还是要强调下字符串匹配的思路 将模式串和主串进行比较 从前往后比较 从后往前比较 2. 匹配时,比较主串和模式串的下一个位置 3. 失配时, 在模式串中寻找一个合适的位置 如果找到 ...
- 大量的数据做字符串匹配_Python Flashtext 实现大数据集下高效的关键词查找和替换...
通常,我们使用Python 在文本中进行关键词查找或替换时,会使用 re 模块以正则的形式实现.在文本数量.文本内容.关键词数量较小时,该方法能够满足我们程序的功能.性能需要.但当在大规模的文本或者对 ...
- 利用双向循环链表实现长整数的存储_重学数据结构之链表篇
本文是重新数据结构系列文章的第二篇,本文和大家一起探讨链表的相关知识. 链表是怎么样的数据结构 链表,不需要连续的内存空间,通过"指针(引用)"将一组零散的内存块串联起来的数据结构 ...
- java 字符串匹配_多模字符串匹配算法原理及Java实现代码
多模字符串匹配算法在这里指的是在一个字符串中寻找多个模式字符字串的问题.一般来说,给出一个长字符串和很多短模式字符串,如何最快最省的求出哪些模式字符串出现在长字符串中是我们所要思考的.该算法广泛应用于 ...
- 重学数据结构与算法(02)--将时间复杂度转换成空间复杂度
将时间复杂度转换成空间复杂度 1)时间昂贵.空间廉价 2)数据结构连接时空 3)降低复杂度的案例 例一 例二 4)总结 面试的过程中,常常会遇到考察手写代码的场景,通常面试官会追问:"这段代 ...
- 重学数据结构——快速排序,二分法查找
每次提起快排,内心中都有点隐隐作痛. 当时腾讯的那个面试官让我写快排的前两遍排序结果,结果,我当时居然没写上来-- 这个,就是所谓的关键时刻掉链子吧,这么经典的快排都不会,真是丢死人了-- 今天在实验 ...
- 数据结构 kmp字符串匹配_用动画解释 KMP 算法
大家好,我是一个每天在互联网都被读者催更催到爆肝,爆肾小鹿童鞋. 说实话,一些数据结构和算法我这辈子都不可能用到实际当中,但个人一直觉得能把复杂的东西讲明白是一件很牛逼的事情. 毕竟想牛逼也是很难的, ...
- python怎么做彩票概率_小白学数据小抄放送 Python,R,大数据,机器学习
原标题:小白学数据小抄放送 Python,R,大数据,机器学习 大数据文摘作品,转载要求见文末 作者 | Elaine,田桂英,Aileen 导读:前段时间小白学数据专栏出了一期Python小抄表,后 ...
- 判断字符串 正则_(重学前端 - JavaScript(模块一)) 14、引用类型之 RegExp (正则)(详述)...
上一篇文章介绍了 JavaScript 中的 Date 类型,从地理方面的原理知识开始入手,如果大家认真看过上一篇文章,相信 JavaScript 中的 Date 类型已经难不住大家了!!! 但是今天 ...
最新文章
- python基础语法手册format-python基础_格式化输出(%用法和format用法)
- 工业机器人行业研究报告
- php artisan 命令列表
- 如何理解并学习javascript中的面向对象(OOP)
- C3P0 释放连接 的问题
- P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包
- 北师大计算机试题五答案,北京师范大学计算机软件及理论2022考研招生分析、参考书、真题等复习指导解析...
- 数字时代企业信息安全如何保障? VMware原生安全前来“保驾护航”
- php如何根据ip查找地址,根据IP地址查找IP所在地
- SIFT算法详解(二)
- php语句导入mysql_php如何将数据库导入mysql
- SpringBoot多数据源切换详解,以及开启事务后数据源切换失败处理
- 降本增效利器!趣头条 Spark Remote Shuffle Service 最佳实践
- 漏型与源型、PNP与NPN
- spss 描述性分析
- 常见浏览器兼容性问题
- html5中display flex,display:flex属性
- Why Would I Ever
- 深度学习·理论篇(2023版)·第001篇快速了解人工智能与Pytorch:机器/表示/深度学习定义+端到端的学习+神经网络在计算机视觉应用+深度学习的技术蓝图
- 蛙蛙推荐:蛙蛙牌网页捕捉器
热门文章
- OneNote中到底能放多少种东西?
- 3.3 修改“时间”维度
- luogu P3178 [HAOI2015]树上操作
- react-native 框架升级 安卓第三方插件报错 Android resource linking failed
- 【原创】大叔问题定位分享(11)Spark中对大表子查询加limit为什么会报Broadcast超时错误...
- [新手学Java]使用beanUtils控制javabean
- Sharing A Powerful Tool For Calculate Code Lines
- VS2013/2012 下无法打开 源 文件“stdafx.h”的解决方法
- 【白皮书下载】2020年数字营销与商业增长白皮书.pdf
- 【报告分享】85后、95后宝妈人群洞察报告.pdf(附下载链接)