前面介绍在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. [小技巧][ASP.Net MVC Hack] 使用 HTTP 报文中的 Header 字段进行身份验证

    在一些 Web 系统中,身份验证是依靠硬件证书进行的:在电脑上插入 USB 证书,浏览器插件读取证书的相关信息,然后在发送 HTTP 登录请求时顺便在 Header 字段附加上身份信息.服务器端处理这 ...

  2. (第二章)Java并发机制的底层实现原理

    一.概述 Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令. ...

  3. Java基础知识强化45:StringBuffer类之字符串反转的案例

    1. 案例演示: package cn.itcast_07; import java.util.Scanner; /* * 把字符串反转 */ public class StringBufferTes ...

  4. BitmapFactory 加载图片到内存

    Bitmap占用内存分析 Android的虚拟机是基于寄存器的Dalvik,它的最大堆(单个进程可用内存)大小一般是16M,当然不同设备是不一样的,可以查看/system/build.prop文件,[ ...

  5. 填坑 - 使用Entity Framework 6 + Sqlite进行DB first开发

    Sqlite团队也是渣啊,到第6代了还不支持Code First. 1.安装运行环境和组件 .安装SQLite的Visual Studio设计器支持 只有安装了它,在[新建ADO.NET实体数据模型] ...

  6. WPF 获取屏幕分辨率(获取最大宽高)等

    double x = SystemParameters.WorkArea.Width;//得到屏幕工作区域宽度 double y = SystemParameters.WorkArea.Height; ...

  7. lib,dll区别 及 VS中如何添加lib,dll

    1.加载lib/头文件 分两种方法: (1)适用于当前项目 第一步:项目->属性->C/C++->常规->附加包含目录(浏览.h文件的路径) 添加包含文件 第二步:项目-> ...

  8. js和jquery中的触发事件

    改别人的坑,遇到jquery选择器和fireEvent混用,不认识fireEvent方法报错. js的方法不能使用jquery的选择器去调用. 1.fireEvent (IE上的js方法 ) 我们来看 ...

  9. ECSTORE导航吸顶功能

    ecstore导航吸顶功能,在导航父元素中加入id,如: <div id="mainNav1"></div> 在footer.html中添加以下js代码: ...

  10. Tr A(HDU 1575 快速矩阵幂模板)

    Tr A Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...