Boyer Moore 算法的C++实现以及一些独特的感受
2014-03-26 23:35
127 查看
关于Boyer Moore算法的实现,小弟我折腾了1周多终于成功了!!!
本人研究了这篇论文:"1977, A fast String Searching Algorithm",总结出以下几个要点:
1. 坏字符算法:
坏字符,就是主串中匹配不上的字符。坏字符算法,就是已知模式串和坏字符,从后往前地搜寻最近一次出现的坏字符(记作bad)。该算法返回的是最后一个字符下标与bad下标之差(如果在整条模式串中找不到坏字符,则把bad下标视作-1)。
2. 好后缀算法:
好后缀,就是从后往前连续匹配上的字符子串,如
主串 ………… innovation……
模式串 creation_activation
“vation” 、”ation“、”tion“、”ion“、”on“、”n”就都是好后缀
好后缀算法,仍然只需知道两个参数:模式串、好后缀在模式串中的中断位置。解释一下,好后缀在模式串的中断位置,在本例中就是字母’i'出现的位置,也就是3。在好后缀算法中要定义两个指针(下标变量)p、q, 分别从模式串的中断位置和末尾位置开始。令p向前逐格移动,若p和q所指的字符相同,则q也向前移动一格,用这种方式寻找最近的一个好后缀。当p和q所指的字符再一次不相同时,中断循环,因为已经匹配到了最佳的好后缀。
该算法返回的是p与末尾下标之差
3. 核心思想:
利用模式串本身的统计学特征,让主串上的指针(记为x)跳跃移动,而不是一步一步地移动。每次跳跃的距离是两种算法的最大值。
4. 出现的问题:
(1) 忽略size_type的非负特性,将其用作下标和控制循环,导致下标溢出错误
(2) 忽略else语句的分支性,导致goodsuffix方法体变成顺序结构。如果字符串完全匹配的话,就会导致goodsuffix访问下标为-1的对象。
本人研究了这篇论文:"1977, A fast String Searching Algorithm",总结出以下几个要点:
1. 坏字符算法:
坏字符,就是主串中匹配不上的字符。坏字符算法,就是已知模式串和坏字符,从后往前地搜寻最近一次出现的坏字符(记作bad)。该算法返回的是最后一个字符下标与bad下标之差(如果在整条模式串中找不到坏字符,则把bad下标视作-1)。
2. 好后缀算法:
好后缀,就是从后往前连续匹配上的字符子串,如
主串 ………… innovation……
模式串 creation_activation
“vation” 、”ation“、”tion“、”ion“、”on“、”n”就都是好后缀
好后缀算法,仍然只需知道两个参数:模式串、好后缀在模式串中的中断位置。解释一下,好后缀在模式串的中断位置,在本例中就是字母’i'出现的位置,也就是3。在好后缀算法中要定义两个指针(下标变量)p、q, 分别从模式串的中断位置和末尾位置开始。令p向前逐格移动,若p和q所指的字符相同,则q也向前移动一格,用这种方式寻找最近的一个好后缀。当p和q所指的字符再一次不相同时,中断循环,因为已经匹配到了最佳的好后缀。
该算法返回的是p与末尾下标之差
3. 核心思想:
利用模式串本身的统计学特征,让主串上的指针(记为x)跳跃移动,而不是一步一步地移动。每次跳跃的距离是两种算法的最大值。
4. 出现的问题:
(1) 忽略size_type的非负特性,将其用作下标和控制循环,导致下标溢出错误
(2) 忽略else语句的分支性,导致goodsuffix方法体变成顺序结构。如果字符串完全匹配的话,就会导致goodsuffix访问下标为-1的对象。
/* * Boyer Moore's Algorithm */ #include <iostream> #include <cstdio> #include <string> #include <algorithm> using namespace std; int badchar(char bad, string& pat); int goodsuffix(int j, string& pat); int boyer_moore(string& text, string& pat); int badchar(char bad, string& pat) { int terminal = pat.length() - 1; int i = terminal; while (i>=0) { if(pat[i]==bad) { return terminal - i; } i--; } return terminal-i; } int goodsuffix(int j, string& pat) { int terminal = pat.length()-1; int tail = terminal; bool encounter = false; while (j>=0) { if (pat[j]==pat[tail]) { encounter = true; tail--; j--; } else if (pat[j]!=pat[tail] && encounter) break; else j--; } return terminal - j; } int boyer_moore (string& str, string& pat) { if (pat.length()>str.length()) return -1; int i = pat.length()-1; anchor: while (i<str.length()) { int j = pat.length()-1; bool matched = false; while (j>=0) { if (str[i]!=pat[j] && matched==false) { i += badchar(str[i], pat); goto anchor; } if (str[i]==pat[j]) { i--; j--; } if (str[i]!=pat[j] && matched==true) { i+= max(badchar(str[i],pat), goodsuffix(j, pat)); goto anchor; } } return i+1; } return -1; } int main() { string a, b; getline(cin, a); getline(cin, b); string &rb = b, &ra=a; cout<<boyer_moore(rb,ra)<<endl; }
相关文章推荐
- adaboost 算法在实现中的一些问题以及解决方法(持续更新)
- GIS矢量数据化简:一种改进的道格拉斯-普克算法以及C++实现
- c++实现加密和解密算法以及JNI技术的应用实例
- 完整的C++实现算法导论十三章红黑树以及十四章中的顺序统计树
- (二叉树)谈一谈各类算法和数据结构的c++实现以及相关操作的复杂度(二)
- [算法导论] 快速排序以及最大堆的C++实现
- 在实现密码学算法的时候用到的一些自创函数以及数据结构
- C++中使用虚函数以及派生类来实现图形的派生后的一些图形的面积
- 一些算法的代码练习(c++实现,编译环境xcode)
- GIS矢量数据化简:一种改进的道格拉斯-普克算法以及C++实现
- 顺序表创建以及查找排序算法(含有顺序查找算法、带哨兵站顺序查找、折半查找算法、冒泡排序)的C++实现在vs2013环境下实现
- 一种改进的道格拉斯-普克算法以及C++实现
- DBSCAN 算法介绍以及C++实现
- PCA算法的原理以及c++实现(Eigen库实现)源码
- 程序员代码面试指南:IT名企算法与数据结构题目最优解-字符串问题:C/C++语言实现
- 支持多位数,括号,四则运算,的计算器算法c++实现
- 一些经典排序算法的实现(C++实现)
- 实习日志3---看图猜名字界面实现,以及基本的一些要求实现
- 实现全排列的两种算法:字典序列法以及递归算法(java)
- 每对顶点间的最短路径算法时间复杂度改进C++实现