前面介绍在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. Java为什么使用连接池

    一.简介 动态Web站点往往用数据库存储的信息生成Web页面,每一个页面请求导致一次数据库访问.连接数据库不仅要开销一定的通信和内存资源,还必须完成用户验证.安全上下文配置这类任务,因为往往成为最为耗 ...

  2. Python 文件I/O (转)

    Python 文件I/O 本章只讲述所有基本的的I/O函数,更多函数请参考Python标准文档. 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个用逗号隔开的表达式.此函数把你 ...

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

    十二.组件(component), 动态组件(dynamic-component) <component>元素把子对象的一些元素与父类对应的表的一些字段映射起来. 然后组件可以定义它们自己 ...

  4. RMQ问题

    关于RMQ的问题我就直接截取刘汝佳的<算法竞赛训练指南>上的解释了

  5. 轻松完成WAP手机网站搭建

    用PHPCMS最新发布的V9搭建了PHPCMS研究中心网站(http://phpcms.org.cn)完成后,有用户提出手机访问的问题,于是着手搭建WAP无线站(wap.phpcms.org.cn). ...

  6. 解决表格里面使用text-overflow后依旧不能隐藏超出的文本

    解决表格里面使用text-overflow后依旧不能隐藏超出的文本 来源: http://blog.csdn.net/colinmuxi/article/details/9069595  (非原创,自 ...

  7. Redis VS Memcached 转载

    引子: 在大数据时代,总希望存在一个Key-value存储机制,像HashMap一样在内存中处理大量(千万数量级)的key-value对,以便提高数据查找.修改速度. 所以,我们会想到,Memcach ...

  8. 如果通过adb查看当前显示的activity

    通过adb 查看最上层成activity名字: linux: adb shell dumpsys activity | grep "mFocusedActivity" window ...

  9. DataSet排序

    //排序            if (ds != null && ds.Tables.Count > 0)            {                DataVi ...

  10. JAVA_build_ant_cmd pass muti param

    ant -f buildFileName -Dpropretyname1=value1  -Dpropretyname2=value2 ant [options] [target [target2 [ ...