您的位置:首页 > 编程语言 > C语言/C++

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的对象。

/*
* 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐