【算法】BM算法
一. 字符串比较的分析
如果要判定长度为\(n\)两个字符串相等,比较中要进行\(n\)比较,但是如果要判定两个字符串不相等,只需要找出一个不相等的位置,因此可以得到如下结论:
结论1:判定字符串相等和判定字符串不相等的代价不同,判定不相等的代价更小
在KMP算法中,每发生一次失配时,算法总是尝试根据已经获得的匹配成功的信息来确定一个新的对齐位置,也即KMP算法是在尝试判断两个字符串相等,根据结论1,这种做法的代价要大于判定字符串不相等的代价。因此BM算法是尝试判定两个字符串不相等。
如果局部匹配成功,对于文本串\(P\)和局部的模式串\(partT\),我们有如下结论:
结论2:
\]
因此文本串\(P\)和局部的模式串\(partT\)对应位置字符相等是匹配成功的一个必要条件,根据这个必要条件我们可以得到BM算法的朴素思想。
二.BM算法的思想
以下面插图为例:

文本串\(T\)和模式串\(P_1\)进行匹配时,文本串中的字符X和模式串中的字符Y失配,此时需要重新选定匹配位置。观察模式串发现,在字符Y的前面,存在一个字符X,此时可以将绿色的X和红色的X对齐,然后再从头开始对比。
当模式串为\(P_2\)时,失配之后发现在字符Y的前面没有字符X,这说明了无论这部分进行怎样的局部匹配,最终都不可能匹配成功。因此可以直接跨过文本串字符X以前的位置。
为了在一次失配出现时能够排除更多的对齐位置,我们考虑不同失配位置的信息量的大小。从下面的插图可以得到结论:
结论3:失配的位置越靠后,能够排除的对齐位置越多
因此BM算法不同于KMP算法,它的每次比对是逆向进行的。

三.算法实现
只要我们记录下每个字符在模式串中的位置,当匹配失败时,找到一个新的位置进行比对即可,为此我们构造一个bc[ ]数组。
考虑两种边界情况:
- 模式串中的字符Y前面不存在字符X;
- 模式串中最右边的字符X在Y的后面;
第一种情况我们只需要令\(bc['X'] = -1\)即可,也就是使用通配哨兵。
第二种情况如果不特殊处理,会使模式串往回移动,出现该种情况使,我们只需要令模式串前进一个单位即可。
算法分为两个部分:构造bc[ ]数组和串匹配。
//构造bc[]
int *buildBc(const string &s){
int *bc = new int [256];//一定要分配空间!!!
for(int i = 0; i < 256; ++i)bc[i] = -1;
for(int i = 0; i < s.size(); ++i)bc[s[i]] = i;
return bc;
}
//串匹配
int bc(const string &s1, const string &s2){
int *bc = buildBc(s2);
int n = s1.size(), m = s2.size();
int i = 0, j = 0;
while(i + m < n){
for(j = m - 1; j >= 0; --j){
if(s1[i + j] != s2[j])break;
}
if(j < 0)break;
int d = max(1, j - bc[s1[i + j]]);
i += d;
}
return i;
}
【算法】BM算法的更多相关文章
- Berlekamp_Massey 算法 (BM算法) 学习笔记
原文链接www.cnblogs.com/zhouzhendong/p/Berlekamp-Massey.html 前言 BM算法用于求解常系数线性递推式. 它可以在 $O(n^2)$ 的时间复杂度内解 ...
- BM算法 Boyer-Moore高质量实现代码详解与算法详解
Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...
- hrbustoj 1551:基础数据结构——字符串2 病毒II(字符串匹配,BM算法练习)
基础数据结构——字符串2 病毒IITime Limit: 1000 MS Memory Limit: 10240 KTotal Submit: 284(138 users) Total Accepte ...
- BM算法详解
http://www-igm.univ-mlv.fr/~lecroq/string/node14.html http://www.cs.utexas.edu/users/moore/publicati ...
- Boyer-Moore(BM)算法,文本查找,字符串匹配问题
KMP算法的时间复杂度是O(m + n),而Boyer-Moore算法的时间复杂度是O(n/m).文本查找中“ctrl + f”一般就是采用的BM算法. Boyer-Moore算法的关键点: 从右遍历 ...
- BM算法
BM算法 用来求解一个数列的递推式. 即给定\(\{x_i\}\)求解一个\(\{a_i\}\),满足\(|a|=m,x_n=\sum_{i=1}^ma_i*x_{n-i}\). 考虑增量法构造. 假 ...
- 数据结构 BM算法
BM算法是比KMP算法更快的字符串模式匹配算法.BM算法最好情况下的时间复杂度是O(n),KMP算法最好情况下的时间复杂度是O(n+m),两者最坏情况下的时间复杂度均是O(m*n).其中,n指目标串长 ...
- BM算法--串匹配
BM(Boyer-Moore)算法,后缀匹配,是指模式串的比较从右到左,模式串的移动也是从左到右的匹配过程,一般情况比KMP算法要快.时间复杂度O(m/n) C++描述(教师版) int BM(cha ...
- BoyerMoore(BM)算法--C#
因项目需要使用字符串查询算法,在网上搜搜了半天,没有找到C#版的. 索性根据BM机制,用C#实现了一遍.现在贴出了,以备忘记. /// <summary> /// BM算法 /// < ...
随机推荐
- wireshark过滤器
一 概况 本文是对wireshark抓包过滤器, 跟显示过滤器的总结 由于一些未知的原因, 这俩过滤器的语法并不一样! 我大概知道为什么不一样了, 因为这俩出现的顺序不一样, 抓包过滤器先出现的, 可 ...
- 使用aliyun cli工具快速创建云主机
参考文档: https://help.aliyun.com/document_detail/25484.html?spm=a2c4g.11186623.3.2.b57vQp 步骤 创建AccessID ...
- 名称 ****不是有效的标识符 sql
假设存储过程:proc_test create proc proc_test @ProdID varchar(10) as begin declare @sql varchar(max) @sql = ...
- 缓存--Redis
Redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...
- 小程序navigateBack,子页面传值给父页面
子页面 let page = getCurrentPages(); let prevPage = page[page.length - 2]; prevPage.setData({ lxr :item ...
- C# xml 读xml、写xml、Xpath、Xml to Linq、xml添加节点 xml修改节点
#region XDocument //创建XDocument XDocument xdoc2 = new XDocument(); XElement xel1= new XElement(" ...
- python_14 多态,封装
多态: 由不同的类实例化得到的对象,调用同一个方法,执行的逻辑不同. 多态的概念指出了对象如何通过他们的共同的属性和动作来操作及访问,而不需考虑他们的类. class H2O: def __init_ ...
- 用es5原生模仿-es6Promise异步处理
用es5原生模仿-es6Promise异步处理,不过在处理异常的时候有点小bug不是很完美,不过多级then 是没问题的和resolve, rejec 正常调用和异常处理调用是没问题的.本帖属于原创 ...
- Netty从入门到精通到放弃
有时间想记录一下关于Netty的知识. 第一课:传统IO的特点. package com.example.aimei.controller; import java.io.InputStream; i ...
- UI设计篇·入门篇·简单动画的实现,为布局设置动画,用XML布置布局动画
不仅仅控件可以设置动画,一个布局也可以设置动画, 当给一个布局设置了动画的时候,这个布局里所包含的控件都会依赖执行这些动画. 为布局设置动画的实现步骤: 1.新建一个动画,设置需要实现的形式 2.新建 ...