对于BMH算法的理解——文本匹配算法
2015-06-04 11:20
393 查看
之前的BM算法已经剔除了大部分的冗余遍历,使得整个的模板匹配算法变得更加高效,但是很明显从例子上就可以看出,有两个缺点一是跨度的时机不能很好的把握,而是仍然有冗余遍历。所以BMH算法被提出来作为BM算法的改进算法。
BMH算法全称是Boyer-Moore-Horspool算法。它不再像BM算法一样关注失配的字符,它的关注的焦点在于匹配文本每一次匹配失败的最后一个字符X,根据这个字符X是否在模板出现过来决定跳跃的步数,否则跳跃模板的长度。
所以分了两种情况:
一:字符X不在模板P中,则跳跃的步数为模板P的长度
二:字符X在模板P中,跳跃的步数为字符X距离离尾部最近的字符X的距离(不包括最后一个字符)
加入文本为missipipi,模板为pip:
只要三次匹配即可。
BMH算法源代码如下(C++版):
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; //如果模板不存在目标字符,则使模板的开始指向目标字符的下一位 else return 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; else cout<<"first appeared place:"<<firstPos<<endl; return 0; }参考文章:《基于BM算法的分布式入侵系统检测系统的研究》
相关文章推荐
- SAP 物料订单创建、下达、报工、收货与投料(ABAP代码)
- 5.机器学习的可行性与数据量关系,突破点
- 冒泡算法
- android二次打包
- Gmail架构相关资料收集
- 最好不要在头文件里面包含定义变量
- imageNamed 与 imageWithContentsOfFile的区别
- c++ 类 helloworld
- Eclipse插件开发 学习笔记 PDF 第一篇到第四篇 免分下载 开发基础 核心技术 高级进阶 综合实例
- 使用异或交换数据值的原理
- HDU 3586
- Nginx 源码结构分析
- SQL in SQL Server Trouble-shooting
- linux sort 命令详解
- iOS学习笔记——数据库操作(SQLite)
- 二分查找法
- java socket 单服务器多客户端实时通信
- OK335xS-Android pack-ubi-256M.sh hacking
- 博客已经搬迁到cofcool.net
- SAT数学:得高分的两个准备