字符串匹配 — Horspool
来源:互联网 发布:小米3屏幕多少钱 淘宝 编辑:程序博客网 时间:2024/05/25 20:00
蛮力法进行字符串匹配的缺点在于每次失配后模式只向后移动一个位置。想要提高算法效率,就必须在不错过文本中一个匹配子串风险的前提下,尽量增大模式向后移动的幅度。Horspool就是这样一种算法之一,它的思想要比KMP算法容易。它采用了输入增加技术:对模式进行预处理得到一些信息,把这些信息存储在表中,当文本和模式进行匹配时就会用到这些信息。Horspool的匹配过程是从右向左进行的,在匹配过程中会出现以下四种情况:
情况1
文本:x x x x A x x x x x
模式: x x B
最后一个字符失配,且模式中不存在文本中的失配字符A,那么模式可以移动的幅度就是它的长度,这里是把模式向后移动3个位置,如下所示:
文本:x x x x A x x x x x
模式: x x B
情况2
文本:x x x x A x x x x x
模式: A x B
最后一个字符失配,且模式中存在文本中的失配字符A,这时应该把模式最右边的A和文本的A对齐,如下所示:
文本:x x x x A x x x x x
模式: A x B
情况3
文本:x x x B A x x x x x
模式: x W A
最后一个字符A相匹配,且模式中剩下的字符都不存在A,那么情况类似于1,移动幅度等于模式的全部长度,如下所示:
文本:x x x B A x x x x x
模式: x W A
情况4
文本:x x x B A x x x x x
模式: A W A
最后一个字符A相匹配,且模式中剩下的字符中存在A,那么情况类似于2,移动模式使二者对齐,如下所示:
文本:x x x B A x x x x x
模式: A W A
从上述过程可以看出,算法的关键是要知道文本中的某个字符(上述过程是字符A)是否在模式中存在,存在的话距模式最后一个字符相差多远。这些信息就是我们要存储在表中的信息。可以以文本中出现的每个字符为c自变量,发生失配时模式可以安全移动的最大距离为函数t(c),得到如下映射:
- 如果c不包含在模式的前m-1个字符中,则t(c) = 模式长度m
- t(c) = 模式前m-1个字符中最右边的c到模式最后一个字符的距离
例如有模式ABCDE,那么在文本的所有字符之中,t(D) = 1,t(C) = 2,t(B) = 3,t(A) = 4,其余字符对应的函数均为模式长度5.对于这种函数映射,用C++的map容器再适合不过了。
以下是完整代码:
#include <iostream>#include <string>#include <map>#include <vector> using namespace std; void Get_Next(const string &text, const string &pattern, map<char, int> &next){ int text_len = text.size(); int pattern_len = pattern.size(); for (int i = 0; i < text_len; i++) next.insert(make_pair(text[i], pattern_len)); for (int i = 0; i < pattern_len - 1; i++) next[pattern[i]] = pattern_len - 1 - i;} void Horspool(const string &text, const string &pattern, vector<int> &result){ int text_len = text.size(); int pattern_len = pattern.size(); map<char, int> next; // 使用map容器记录移动表 Get_Next(text, pattern, next); for (int i = pattern_len - 1; i < text_len; /* NULL */) { int text_pos = i; int pattern_pos; for (pattern_pos = pattern_len - 1; pattern_pos >= 0; /* NULL */) { if (text[text_pos] == pattern[pattern_pos]) { text_pos--; pattern_pos--; } else { i += next[text[i]]; // i = 文本中对齐模式最后一个字符的位置 break; } } if (pattern_pos <= 0) { result.push_back(i - pattern_len + 1); // 完全匹配时的起始位置 i++; } }} int main(){ string text = "hello world good google Nestle people google hello this is a test google"; string pattern = "google"; vector<int> result; Horspool(text, pattern, result); int cnt = 1; for (vector<int>::iterator iter = result.begin(); iter != result.end(); ++iter) cout << "match " << cnt++ << " = " << *iter << endl; system("pause"); return 0;}
运行结果:
对于随机文本,Horspool算法的效率为Θ(n),n为文本长度。
参考:
《算法设计与分析基础》 P194-P197.
0 0
- 字符串匹配 — Horspool
- Horspool字符串匹配算法
- Horspool字符串匹配算法
- Horspool字符串匹配算法
- HorsPool字符串匹配算法
- 字符串匹配算法horspool
- Horspool(字符串匹配)算法
- 字符串匹配之Horspool算法
- 字符串匹配之horspool算法
- 字符串匹配算法 之 (Horspool )Boyer-Moore-Horspool
- 【算法学习】horspool查找匹配字符串
- 快速字符串模糊匹配--基于Horspool的模糊匹配算法
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽
- Unity3D使用经验总结 编辑器扩展篇
- CheckBoxPreference--数据存储
- NSArray常用用法学习记录
- 如何简单快速获取SharePoint列表的GUID
- dede如何让文章增加原创版权连接
- 字符串匹配 — Horspool
- 炉石传说 C# 开发笔记 (源代码整理公开)
- Ubuntu 12.10下解压文件名称乱码的问题解决
- opengl 教程(4) shader(1)
- Android NewEditText类
- 【反射】——Autofac 类型注册
- 传统企业在移动互联网时代的转变-薛雯漪
- 使用easyui过程中遇到的问题及解决方案积累中...
- (知其所以然 主题3)论观察者模式之KVC和KVO