前面介绍在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]移动到该位置之后,

    

      j=3时发生了不匹配,此时移动步伐(step)=j+1=4.

    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; //匹配失败
}

四、写在后面的话

字符串匹配这个系列,加上这篇已经写的有4篇文章了,这个系列还剩最后一个算法没有写,有时间了把最后一个算法补上后就这个系列就算是Over了。

假设你认为本篇对你有收获,请帮顶。

另外,我开通了微信公众号--分享技术之美,我会不定期的分享一些我学习的东西.
你能够搜索公众号:swalge 或者扫描下方二维码关注我

(转载文章请注明出处: http://blog.csdn.net/swagle/article/details/24269403 )




字符串匹配之horspool算法(简化的BM算法)的更多相关文章

  1. 算法——字符串匹配之BM算法

    前言 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法(简称BM算法),后缀匹配就是模式串从右到左開始比較,但模式串的移动依旧是从左到右的.在实践中.BM算法效率高于前面介绍的<KM ...

  2. Sunday算法解决字符串匹配问题

    概述 提起字符串匹配可能更多人会想到KMP算法,该算法时间复杂度为O(m+n),而且也是我们在学习数据结构过程中最早接触到的比较好的算法.但KMP算法需要在模式字符串有关联的情况下,也即模式字符串前后 ...

  3. Luogu 3375 【模板】KMP字符串匹配(KMP算法)

    Luogu 3375 [模板]KMP字符串匹配(KMP算法) Description 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来 ...

  4. 字符串匹配 扩展KMP BM&Sunday

    复杂度都是O(n) 扩展1:BM算法 KMP的匹配是从模式串的开头开始匹配的,而1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹 ...

  5. 字符串匹配算法(二)-BM算法详解

    我们在字符串匹配算法(一)学习了BF算法和RK算法,那有没更加高效的字符串匹配算法呢.我们今天就来聊一聊BM算法. BM算法 我们把模式串和主串的匹配过程,可以看做是固定主串,然后模式串不断在往后滑动 ...

  6. hrbustoj 1551:基础数据结构——字符串2 病毒II(字符串匹配,BM算法练习)

    基础数据结构——字符串2 病毒IITime Limit: 1000 MS Memory Limit: 10240 KTotal Submit: 284(138 users) Total Accepte ...

  7. Boyer-Moore(BM)算法,文本查找,字符串匹配问题

    KMP算法的时间复杂度是O(m + n),而Boyer-Moore算法的时间复杂度是O(n/m).文本查找中“ctrl + f”一般就是采用的BM算法. Boyer-Moore算法的关键点: 从右遍历 ...

  8. 字符串匹配常见算法(BF,RK,KMP,BM,Sunday)

    今日了解了一下字符串匹配的各种方法. 并对sundaysearch算法实现并且单元. 字符串匹配算法,是在实际工程中经常遇到的问题,也是各大公司笔试面试的常考题目.此算法通常输入为原字符串(strin ...

  9. 字符串匹配KMP算法的讲解C++

    转自http://blog.csdn.net/starstar1992/article/details/54913261 也可以参考http://blog.csdn.net/liu940204/art ...

随机推荐

  1. Eclipse 添加快捷方式

    1.在/usr/share/applications创建一个desktop文件,命名为eclipse.desktop 文件内容如下 [Desktop Entry]Name=EclipseType=Ap ...

  2. 2、第2节课html教程客户端控件/css第一课/20150917

    1.<form> 标签 提交 <form action="http://www.baidu.com" method="post'> </fo ...

  3. NHIBERNATE之映射文件配置说明(转载4)

    二十.自定义值类型   开发者创建属于他们自己的值类型也是很容易的.比如说,你可能希望持久化Int64类型的属性, 持久化成为VARCHAR 字段.NHibernate没有内置这样一种类型.自定义类型 ...

  4. 回顾:Linq To SQL语法 - 实体类

    第一篇博客,还望各位大神勿喷 小弟在此代码奉上........ 借用NorthWind数据库,实现一个商品展示的小功能.上代码: 添加对Linq的引用 using System.Data.Linq;/ ...

  5. 动态绑定、阻止继承,final类和方法

    1.编译器查看对象的声明类型和方法名.当调用 x.f(param); 且隐式参数x生命为C类对象.这时候可能有多个名字都叫f,但是参数类型不一样的方法.编译器会一一列举C类中名为f的方法和其超类中访问 ...

  6. typedef std::string AddressLines[4]定义了一个string数组,大小为4

    int main() { typedef std::]; std::]; std::string *pal1 = new AddressLines; delete [] pal; delete [] ...

  7. 你好,C++(20).4.2.2 表达并列条件选择的switch语句:如果……如果……如果……

    4.2.2  表达并列条件选择的switch语句:如果……如果……如果…… 在现实世界中,还有这样一类特殊的条件选择: 如果明天是晴天,我就穿T恤: 如果明天是阴天,我就穿衬衣: 如果明天是雨天,我就 ...

  8. php对象中类的继承性访问类型控制

    类型的访问控制通过使用修饰符允许开发人员对类中成员的访问进行限制.这是PHP5的新特性,也是OOP语言中的重要特性,大多数OOP语言都已支持此特性.PHP5支持如下三种访问修饰符,在类的封装中我们已经 ...

  9. PHP面向对象的构造方法与析构方法

    构造方法与析构方法是对象中的两个特殊方法,它们都与对象的生命周期有关.构造方法时对象创建完成后第一个被对象自动调用的方法,这是我们在对象中使用构造方法的原因.而析构方法时对象在销毁之前最后一个被对象自 ...

  10. python之6-1常用函数

    1.休眠函数 import time time.sleep(n) n可以是整数或者小数,单位是秒 2.打开文件函数 open('n','m',k) n是文件路径,如果只有文件名,则是py程序所在文件夹 ...