之前的BM算法已经剔除了大部分的冗余遍历,使得整个的模板匹配算法变得更加高效,但是很明显从例子上就可以看出,有两个缺点一是跨度的时机不能很好的把握,而是仍然有冗余遍历。所以BMH算法被提出来作为BM算法的改进算法。

BMH算法全称是Boyer-Moore-Horspool算法。它不再像BM算法一样关注失配的字符,它的关注的焦点在于匹配文本每一次匹配失败的最后一个字符X,根据这个字符X是否在模板出现过来决定跳跃的步数,否则跳跃模板的长度。

所以分了两种情况:

一:字符X不在模板P中,则跳跃的步数为模板P的长度

二:字符X在模板P中,跳跃的步数为字符X距离离尾部最近的字符X的距离(不包括最后一个字符)

加入文本为missipipi,模板为pip:

只要三次匹配即可。

BMH算法源代码如下(C++版):

#include <iostream>
#include <string.h>using namespace std;///计算模板一般情况下的滑动窗口
void getShiftFrame(int* table, int len,  string needle)
{int i = 0;//存储字符距离最右端的距离,重复字符只存最右端距离 for(; i < len; i++)table[needle[i]] = i;
}//计算模板应该滑动的距离
int Dist_BMH(char target, int* table, int len){//如果模板存在目标字符,则返回与右端的距离作为滑动距离 if(table[target] > -1)return len - table[target] - 1;//如果模板不存在目标字符,则使模板的开始指向目标字符的下一位 elsereturn len;
}//BMH Search算法
int BMHSearch(string haystack,string needle)
{int n = haystack.size() - 1;//haystack长度 int m = needle.size() - 1;//needle长度 if(m == -1) return 0; if(m > n) return -1;int i = m, k = m, q = m;//i是haystack的指针,k是needle的指针,q是记录现在滑动的点,也就是needle滑动到haystack的位置 int* table = new int[256];//创建一个保存滑动距离的窗口 for(i = 0; i < 256; i++)table[i] = -1;i = m;getShiftFrame(table, m,needle);//计算模板一般情况下的滑动窗口 while(i <= n){//从后往前匹配,若成功则返回下标,否则取得滑动距离,使模板滑动到对应的位置 if(haystack[i] == needle[k]){if(k == 0)return i;else{k--;i--;}}else{i = q + Dist_BMH(haystack[q], table, m + 1);q = i;k = m; }} return -1;
}int main()
{string haystack = "abbc";string needle = "bc";int firstPos = BMHSearch(haystack, needle);if(firstPos < 0)cout<<"search failed\n"<<endl;elsecout<<"first appeared place:"<<firstPos<<endl;return 0;
}

参考文章:《基于BM算法的分布式入侵系统检测系统的研究》

对于BMH算法的理解——文本匹配算法相关推荐

  1. 字符串匹配——BMH算法

    字符串匹配--BMH算法 给定主串T和模式串P,返回P在T中首次出现的位置,如果P不存在于T中,返回-1. 这样的问题就是字符串匹配问题,这里给出BMH算法的思想. 设主串T的长度为n,模式串P的长度 ...

  2. 【算法】从后向前的字符串匹配算法——BMH算法+sunday算法

    前言 KMP算法将从前向后的字符串匹配的效率发挥到了极致,所以想要进一步提升,只能打破思维定式,找到一条与众不同的路.所以从后往前的字符串匹配算法就应运而生.它可以更为高效的快速移动字符串,但是在最坏 ...

  3. 特定领域知识图谱融合方案:文本匹配算法ERNIE-Gram单塔等诸多模型【_副本

    #★★★本文源自AlStudio社区精品项目, [点击此处]查看更多精品内容 >>> (https://aistudio.baidu.com/aistudio/proiectover ...

  4. minhash算法检索相似文本_文本去重算法:Minhash/Simhash/Klongsent

    日前接到一个对名言警句这种短文本进行去重的小任务,下图是几个重复文本的示例: 很直观的结论就是重复度越高的文本,具有更多重复的词汇.一个最直接的去重思路可以描述为:将文本进行分词处理,统计各文本词汇的 ...

  5. React中diff算法的理解

    React中diff算法的理解 diff算法用来计算出Virtual DOM中改变的部分,然后针对该部分进行DOM操作,而不用重新渲染整个页面,渲染整个DOM结构的过程中开销是很大的,需要浏览器对DO ...

  6. Vue中diff算法的理解

    Vue中diff算法的理解 diff算法用来计算出Virtual DOM中改变的部分,然后针对该部分进行DOM操作,而不用重新渲染整个页面,渲染整个DOM结构的过程中开销是很大的,需要浏览器对DOM结 ...

  7. python nlp文本摘要实现_用TextRank算法实现自动文本摘要

    [51CTO.com快译]1. 引言 文本摘要是自然语言处理(NLP)领域中的应用之一,它必将对我们的生活产生巨大影响.随着数字媒体和出 版业的不断发展,谁还有时间浏览整篇文章/文档/书籍来决定它们是 ...

  8. python数据获取与文本分析_python文本分析之处理和理解文本

    前言: 在进行自然语言的建模(NLP)时,我们通常难以处理文字类型的数据,因此在常见的机器学习项目中,数据的格式是结构化的,就算在视觉处理的时候也是一个矩阵或者高维张量的形式.那么文字类型的数据我们应 ...

  9. 匹配字符串之——KMP算法深入理解

    KMP算法的用途 一般在字符串匹配的时候,我们通常想到的就是使用KMP算法来处理. KMP的使用,在网上有很多实例,但是讲得很让人容易接受的不是很多,但总感觉那层窗户纸没有捅破,这里我结合前人的知识, ...

最新文章

  1. OpenCV查找边缘
  2. AIX 7.1 使用installp安装python的方法
  3. php酷狗音乐json,用php来搜索酷狗音乐
  4. sql 一列中平均应发工资_劳动者的工资标准,应如何认定?
  5. Java Integer常量池——IntegerCache内部类
  6. vs2010无法添加dll引用
  7. 小工具:(求ASCII码值)
  8. 虚拟机(VMWARE)安装的系统如何访问本地磁盘
  9. 傲梅分区助手 linux,傲梅分区助手(详解磁盘操作)
  10. iOS12.4完整越狱来了,附手机端一键越狱教程!
  11. 拼多多API接口(附上我的可用API)
  12. scala当中的文件操作、网络请求和隐式转换
  13. 读书笔记 - -《Python网络编程》重点
  14. 二极管的分类及常用方法
  15. 略谈为学之道和未来之大学
  16. matlab dae,matlab用ode15数值计算微分代数方程(DAE)的问题
  17. 【毕业设计/matlab系列】基于ADPCM压缩标准的音频压缩和解压缩实现【含Matlab源码】
  18. CAPL函数Test Node中,关闭总线,关闭节点,停发报文应该怎么做?
  19. 2015年最受欢迎的十篇神秘的程序员漫画
  20. 将灰度图像变换到0-1的灰度范围

热门文章

  1. 关于出国读博与国内爱情的一些思考
  2. OPPO互联网java后端二面题目
  3. 微信偷偷更新了一个emoji表情!
  4. 项目可行性的研究内容
  5. ILSSI认证|六西格玛绿带、黑带证书|优思学院
  6. 在springboot中使用Thumbnailator缩略图片
  7. 当技术遇见战略咨询:IBM企业咨询2.0助力传统企业逆袭
  8. 中国近地表日气温数据集
  9. 试卷分析的四个度:难度、区分度、信度、效度
  10. B.FRIENDit壁虎忍者办公静音巧克力有线键盘的特色有哪些呢?