前面介绍在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'].



三、实现

  1. //update 2014-06-07
  2. int horspool(const char *S, const char *T){
  3. if(S==NULL || T==NULL) return -1;
  4. int n = strlen(S);
  5. int m = strlen(T);
  6. int table[256] = {-1};
  7. //记录模式串中字符出现的最右位置
  8. for(int i=0; i<m; ++i)
  9. table[ T[i] ] = i;
  10. //移动步伐
  11. int step = 0;
  12. for(int i=0; i+m<=n; i+=step){
  13. step = 0;
  14. //開始匹配,从右往左匹配
  15. for( int j=m-1; j>=0; --j){
  16. if( S[i+j] != T[j] ){
  17. step = j-table[ S[i+j] ];
  18. //防止原地踏步
  19. if(step <1 ) step = 1;
  20. //本轮匹配失败,从新位置開始比較
  21. break;
  22. }
  23. }
  24. //一轮匹配结束后,没有匹配失败的,说明匹配成功
  25. if(step == 0) return i;
  26. }
  27. return -1; //匹配失败
  28. }

四、写在后面的话

字符串匹配这个系列,加上这篇已经写的有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. UITextField点击return后注销第一响应者

    // 当点击了return按钮,就让text调用自己的endEditing方法 [textField addTarget:textField action:@selector(endEditing:) ...

  2. SplitButton( 分割按钮)

    一. 加载方式//class 加载方式<a href="javascript:void(0)" id="edit" class="easyui- ...

  3. Java多线程练习二

    public class ex3 { public static void main(String [] args) { thread2 t1 = new thread2("hello&qu ...

  4. 使用Gird++打印出现“Retrieving the COM class factory for component with CLSID”的解决办法

    我们的接口需要返回一个gird++生成PDF文件的二进制数据,在本地测试都很好,发布到服务器上一直出现“Retrieving the COM class factory for component w ...

  5. 掌众android面试题

    1,android动画分类? http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html 2,android service启动 ...

  6. jQuery1.9(辅助函数)学习之——.serialize();

    $("form").serialize();  返回一个String 描述: 将用作提交的表单元素的值编译成字符串,这个方法不接受任何参数. .serialize(); 方法使用标 ...

  7. JS原型的剖析与理解

    原型相关的概念 关于面向对象的概念 类 class 在js中就是构造函数 在传统的面向对象语言中,使用一个叫类的东西定义模版,然后使用模版创建对象 在构造方法中也具有类似的功能,因此称其为类 实例与对 ...

  8. transition Css3过度详解

    过度语法: .example { transition-property: background-color; //需要过度的css属性 transition-duration: 2s; //过度所需 ...

  9. [算法]分治算法(Divide and Conquer)

    转载请注明:http://www.cnblogs.com/StartoverX/p/4575744.html 分治算法 在计算机科学中,分治法是建基于多项分支递归的一种很重要的算法范式.字面上的解释是 ...

  10. Spark问题记录

    Spark 多线程时的序列化问题  临时记录 Exception in thread "Thread-28" org.apache.spark.SparkException: Ta ...