整理日: 2015年2月16日

1. 主要特征

假设文本串text长度为n,模式串pattern长度为m,BM算法的主要特征为:

  • 从右往左进行比较匹配(一般的字符串搜索算法如KMP都是从从左往右进行匹配);
  • 算法分为两个阶段:预处理阶段和搜索阶段;
  • 预处理阶段时间和空间复杂度都是是O(m+sigma),sigma是字符集大小,一般为256;
  • 搜索阶段时间复杂度是O(mn);
  • 当模式串是非周期性的,在最坏的情况下算法需要进行3n次字符比较操作;
  • 算法在最好的情况下达到O(n / m),比如在文本串bn中搜索模式串am-1b ,只需要n/m次比较。

2. 算法基本思想

常规的匹配算法移动模式串的时候是从左到右,而进行比较的时候也是从左到右的,基本框架是:

while(j <= strlen(text) - strlen(pattern)){
for (i = 0; i < strlen(pattern) && pattern[i] == text[i + j]; ++i); if (i == strlen(pattern)) {
Match;
break;
}
else
++j;
}

而BM算法在移动模式串的时候是从左到右,而进行比较的时候是从右到左的,基本框架是:

while(j <= strlen(text) - strlen(pattern)){
for (i = strlen(pattern); i >= 0 && pattern[i] == text[i + j]; --i); if (i < 0)) {
Match;
break;
}
else
j += BM();
}

3. 实例:算法整合

#include <stdio.h>
#include <string.h> #define MAX_CHAR 256
#define SIZE 256
#define MAX(x, y) (x) > (y) ? (x) : (y) void BoyerMoore(char *pattern, int m, char *text, int n); int main()
{
char text[256], pattern[256]; while(1)
{
scanf("%s%s", text, pattern);
if(text == 0 || pattern == 0) break; BoyerMoore(pattern, strlen(pattern), text, strlen(text));
printf("\n");
} return 0;
} void print(int *array, int n, char *arrayName)
{
int i;
printf("%s: ", arrayName);
for(i = 0; i < n; i++)
{
printf("%d ", array[i]);
}
printf("\n");
} void PreBmBc(char *pattern, int m, int bmBc[])
{
int i; for(i = 0; i < MAX_CHAR; i++)
{
bmBc[i] = m;
} for(i = 0; i < m - 1; i++)
{
bmBc[pattern[i]] = m - 1 - i;
} /* printf("bmBc[]: ");
for(i = 0; i < m; i++)
{
printf("%d ", bmBc[pattern[i]]);
}
printf("\n"); */
} void suffix_old(char *pattern, int m, int suff[])
{
int i, j; suff[m - 1] = m; for(i = m - 2; i >= 0; i--)
{
j = i;
while(j >= 0 && pattern[j] == pattern[m - 1 - i + j]) j--; suff[i] = i - j;
}
} void suffix(char *pattern, int m, int suff[]) {
int f, g, i; suff[m - 1] = m;
g = m - 1;
for (i = m - 2; i >= 0; --i) {
if (i > g && suff[i + m - 1 - f] < i - g)
suff[i] = suff[i + m - 1 - f];
else {
if (i < g)
g = i;
f = i;
while (g >= 0 && pattern[g] == pattern[g + m - 1 - f])
--g;
suff[i] = f - g;
}
} // print(suff, m, "suff[]");
} void PreBmGs(char *pattern, int m, int bmGs[])
{
int i, j;
int suff[SIZE]; // 计算后缀数组
suffix(pattern, m, suff); // 先全部赋值为m,包含Case3
for(i = 0; i < m; i++)
{
bmGs[i] = m;
} // Case2
j = 0;
for(i = m - 1; i >= 0; i--)
{
if(suff[i] == i + 1)
{
for(; j < m - 1 - i; j++)
{
if(bmGs[j] == m)
bmGs[j] = m - 1 - i;
}
}
} // Case1
for(i = 0; i <= m - 2; i++)
{
bmGs[m - 1 - suff[i]] = m - 1 - i;
} // print(bmGs, m, "bmGs[]");
} void BoyerMoore(char *pattern, int m, char *text, int n)
{
int i, j, bmBc[MAX_CHAR], bmGs[SIZE]; // Preprocessing
PreBmBc(pattern, m, bmBc);
PreBmGs(pattern, m, bmGs); // Searching
j = 0;
while(j <= n - m)
{
for(i = m - 1; i >= 0 && pattern[i] == text[i + j]; i--);
if(i < 0)
{
printf("Find it, the position is %d\n", j);
j += bmGs[0];
return;
}
else
{
j += MAX(bmBc[text[i + j]] - m + 1 + i, bmGs[i]);
}
} printf("No find.\n");
}

字符串搜索算法Boyer-Moore的更多相关文章

  1. Boyer–Moore (BM)字符串搜索算法

    在计算机科学里,Boyer-Moore字符串搜索算法是一种非常高效的字符串搜索算法.它由Bob Boyer和J Strother Moore设计于1977年.此算法仅对搜索目标字符串(关键字)进行预处 ...

  2. grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)

    这篇长文历时近两天终于完成了,前两天帮网站翻译一篇文章“为什么GNU grep如此之快?”,里面提及到grep速度快的一个重要原因是使用了Boyer-Moore算法作为字符串搜索算法,兴趣之下就想了解 ...

  3. grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)(转)

    这篇长文历时近两天终于完成了,前两天帮网站翻译一篇文章“为什么GNU grep如此之快?”,里面提及到grep速度快的一个重要原因是使用了Boyer-Moore算法作为字符串搜索算法,兴趣之下就想了解 ...

  4. 从入门到精通之Boyer-Moore字符串搜索算法详解

    本文讲述的是Boyer-Moore算法,Boyer-Moore算法作为字符串搜索算法,兴趣之下就想了解这个算法,发现这个算法一开始还挺难理解的,也许是我理解能力不是很好吧,花了小半天才看懂,看懂了过后 ...

  5. Boyer Moore算法(字符串匹配)

    上一篇文章,我介绍了KMP算法. 但是,它并不是效率最高的算法,实际采用并不多.各种文本编辑器的"查找"功能(Ctrl+F),大多采用Boyer-Moore算法. Boyer-Mo ...

  6. Leetcode OJ : Implement strStr() [ Boyer–Moore string search algorithm ] python solution

    class Solution { public: int strStr(char *haystack, char *needle) { , skip[]; char *str = haystack, ...

  7. BF + KMP + BM 字符串搜索算法

    BF #include <stdio.h> #include <string.h> int simplicity(char *s, char *t, int pos); int ...

  8. Google Interview University - 坚持完成这套学习手册,你就可以去 Google 面试了

    作者:Glowin链接:https://zhuanlan.zhihu.com/p/22881223来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 原文地址:Google ...

  9. 字符串核对之Boyer-Moore算法

    算法说明: 在计算机科学里,Boyer-Moore字符串搜索算法是一种非常高效的字符串搜索算法.它由Bob Boyer和J Strother Moore设计于1977年.此算法仅对搜索目标字符串(关键 ...

随机推荐

  1. 英文Ubantu系统安装中文输入法

    以前都是安装的中文Ubantu,但是有时候用命令行的时候中文识别不好,会出现错误,所以这次安装了英文版,但是安装后发现输入法不好用,于是就要自己安装输入法. 安装环境为Ubantu13.04 1.卸载 ...

  2. UDP编程

    一: socket编程中的几种地址 Socket编程会遇到三种地址, 都是定义的结构体(struct): Struct in_addr     {         Unsigned int s_add ...

  3. rnqoj-99-配置魔药-dp

    比较好的题目~~ dp[j][k]: 第一个容器在第i秒和第二个容器在第j秒,所产生的最大魔力. if(num[i].t2<=j)dp[j][k]=max(dp[j][k],dp[num[i]. ...

  4. John(博弈)

    Description Little John is playing very funny game with his  younger brother. There  is one big box ...

  5. Eclipse3.7中搭建Android开发环境文档教程和视频教程

    1.下载Eclipse3.7,登录http://www.eclipse.org/downloads/,下载Eclipse Classic 3.7: 2.安装ADT插件:下载好Eclipse后解压,运行 ...

  6. DataGrid列的合并

    /// <summary> /// DataGrid列的合并 /// 注意:1.DataGrid在绑定的时候进行分组和排序,才能让相同的行放在一起 /// 2.方法应用的时机,应该在Dat ...

  7. IIS 上发布ASP.NET5

    原文 http://docs.asp.net/en/latest/publishing/iis.html 1.安装HTTP Platform Handler ,这个是必需的,不然无法通过IIS访问AS ...

  8. 无法绑定到新的显示成员,参数名:newDisplayMember

    此问题不是网上说的 DisplayMember 等先后顺序问题,即使更换绑定数序,只是把错误覆盖而已(绑定的是对象的类名) ValueMember = "Id"; DisplayM ...

  9. easyui实现datagrid数字排序问题

    我们在使用easyui对列进行自动排序的时候(即顺序倒序),正常情况下是通过设置field中的sortable:true属性来控制是否可以排序.但是我们会发现一个有趣的问题,在对数字进行排序的时候,这 ...

  10. Net的struct的内存对齐问题

    很少有人谈起struct的内存对齐问题, 就是在很多C#书中, 也很少提及. 但在实际应用中, 如果不注意内存对齐, struct比较大的话, 则会浪费一定的内存.    先从一个实例看起. publ ...