字符串匹配之horspool算法(简化的BM算法)
前面介绍在BF,KMP这些算法的时候老是提到BM这个东西,究竟这什么东西,有啥高深的,这些问题我们如今不去考虑。不知道,认真读前几篇文章的读者有没有发现前面的算法都是从模式串的前面開始匹配的,那我们就想能不能从模式串的后面開始匹配了? 答案肯定是能够的。所以这就有了我们今天的这篇文章Horspool算法,这个算法是基于字符串后缀的匹配算法。
在上一篇文章中,我们学习了一个概念叫好字符(又叫好后缀),大家都知道有好必有坏吧,所以我们今天再来学习一个概念-----坏字符。
一、坏字符与模式串滑动
坏字符是串S中引起匹配失败的字符,坏字符又能够分为两类:
1. 坏字符不在模式串T中,例如以下样例
S: "abbadcababacab", T: "babac", 串S中的字符d就是一个坏字符
对于这样的情况,我们直接把模式串向后移动使其T[0]与d的下一位对其,然后从后開始进行下一轮匹配;
2. 坏字符串在模式串中,如上面样例移动后,从后往前比較,b和c不同样,而字符b在模式串T中出现,此时就把模式串移动到模式串的该字符和串的该坏字符对其,可是假设该坏字符在模式串种出现了不止一次,我们怎么移动了?这时候,为了保守起见,我们移动模式串使模式串种最右端的坏字符和串的该坏字符对其,例如以下:
假设依照最以下的方法移动,和最左端的字符对其,则可能会漏掉匹配项,如上图所看到的。
二、知道了坏字符和怎样滑动模式串了,计算移动步伐step
代码的难处在遇到坏字符后该怎样移动模式串,即计算移动步伐(step)。
1. 对于第一种情况,坏字符不在模式串中,直接就T[0]移动到该位置之后,
2. 对于另外一种情况,坏字符在模式串中,为了得到该字符在模式串中的最右位置,须要有一个表记录坏字符在模式串中的最右位置,设其为table[i], 则步伐step= j-table['e'].
三、实现
//update 2014-06-07
int horspool(const char *S, const char *T){
if(S==NULL || T==NULL) return -1;
int n = strlen(S);
int m = strlen(T);
int table[256] = {-1};
//记录模式串中字符出现的最右位置
for(int i=0; i<m; ++i)
table[ T[i] ] = i;
//移动步伐
int step = 0;
for(int i=0; i+m<=n; i+=step){
step = 0;
//開始匹配,从右往左匹配
for( int j=m-1; j>=0; --j){
if( S[i+j] != T[j] ){
step = j-table[ S[i+j] ];
//防止原地踏步
if(step <1 ) step = 1;
//本轮匹配失败,从新位置開始比較
break;
}
}
//一轮匹配结束后,没有匹配失败的,说明匹配成功
if(step == 0) return i;
}
return -1; //匹配失败
}
四、写在后面的话
另外,我开通了微信公众号--分享技术之美,我会不定期的分享一些我学习的东西.
(转载文章请注明出处: http://blog.csdn.net/swagle/article/details/24269403 )
字符串匹配之horspool算法(简化的BM算法)的更多相关文章
- 算法——字符串匹配之BM算法
前言 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法(简称BM算法),后缀匹配就是模式串从右到左開始比較,但模式串的移动依旧是从左到右的.在实践中.BM算法效率高于前面介绍的<KM ...
- Sunday算法解决字符串匹配问题
概述 提起字符串匹配可能更多人会想到KMP算法,该算法时间复杂度为O(m+n),而且也是我们在学习数据结构过程中最早接触到的比较好的算法.但KMP算法需要在模式字符串有关联的情况下,也即模式字符串前后 ...
- Luogu 3375 【模板】KMP字符串匹配(KMP算法)
Luogu 3375 [模板]KMP字符串匹配(KMP算法) Description 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来 ...
- 字符串匹配 扩展KMP BM&Sunday
复杂度都是O(n) 扩展1:BM算法 KMP的匹配是从模式串的开头开始匹配的,而1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹 ...
- 字符串匹配算法(二)-BM算法详解
我们在字符串匹配算法(一)学习了BF算法和RK算法,那有没更加高效的字符串匹配算法呢.我们今天就来聊一聊BM算法. BM算法 我们把模式串和主串的匹配过程,可以看做是固定主串,然后模式串不断在往后滑动 ...
- hrbustoj 1551:基础数据结构——字符串2 病毒II(字符串匹配,BM算法练习)
基础数据结构——字符串2 病毒IITime Limit: 1000 MS Memory Limit: 10240 KTotal Submit: 284(138 users) Total Accepte ...
- Boyer-Moore(BM)算法,文本查找,字符串匹配问题
KMP算法的时间复杂度是O(m + n),而Boyer-Moore算法的时间复杂度是O(n/m).文本查找中“ctrl + f”一般就是采用的BM算法. Boyer-Moore算法的关键点: 从右遍历 ...
- 字符串匹配常见算法(BF,RK,KMP,BM,Sunday)
今日了解了一下字符串匹配的各种方法. 并对sundaysearch算法实现并且单元. 字符串匹配算法,是在实际工程中经常遇到的问题,也是各大公司笔试面试的常考题目.此算法通常输入为原字符串(strin ...
- 字符串匹配KMP算法的讲解C++
转自http://blog.csdn.net/starstar1992/article/details/54913261 也可以参考http://blog.csdn.net/liu940204/art ...
随机推荐
- Java开发者易犯错误Top10
本文总结了Java开发者经常会犯的前十种错误列表. Top1. 数组转换为数组列表 将数组转换为数组列表,开发者经常会这样做: List<String> list = Arrays.asL ...
- 常用元素的属性/方法 attr / val / html /text
常用元素的属性/方法 得到一个元素的高度, $("#myid").height() 得到一个元素的位置, $("#myid").offset() 返回的是一个o ...
- C# 无边框窗体移动代码
C# 无边框窗体移动代码 Point _frmPoint = new Point(); //移动前窗体左上角坐标 Point _mousePoint = new Point(); //按下鼠标时坐标 ...
- linux 各种发行版及包管理器的关系
linux 各种发行版及包管理器的关系 Linux发行版列表 基于Kpkg(Debian 系) Debian GNU / Linux 及其派生发行版使用deb软件包格式,并使用dpkg及其前端作为包管 ...
- c - 逆序/正序输出每位.
#include <stdio.h> #include <math.h> /* 判断一个正整数的位数,并按正序,逆序输出他们的位. */ int invert(int); vo ...
- Sql Server 2008清理数据库日志的语句
USE [master]GOALTER DATABASE DNName SET RECOVERY SIMPLE WITH NO_WAITGOALTER DATABASE DNName SET RECO ...
- asp.net 发送邮件代码 System.Net.Mail
前台页面 SendEmail.aspx 代码 using System.Net.Mail;using System.Net; <h2> 发送电子邮件演示 </h2> <t ...
- Heroku 部署时 time out 错误,对GFW无力吐槽!!!
整理自:http://ruby-china.org/topics/10813 部署到Heroku时输入 git push heroku master. 然后就开始漫长的等待了,最终报错: ssh: c ...
- 同步关键字synchronized
同步关键字synchronized 同步关键字synchronized使用简洁,代码可维护性好.在JDK6中,性能也比早期的JDK有很大的改进.如果可以满足程序要求,应该首先考虑这种同步方式. 关键字 ...
- ECSTORE 货币格式
世界上许多国家都有不同的货币 格局和数字 格局 特例 .针对特定的当地化环境正确地 格局化和显示货币是当地化的一个主要部分,ecstore 可以同过后台的设置,来更改货币的格式,具体方式为 后台-&g ...