整理日: 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. C# 自定义事件

    C#自定义事件和java有所不同,涉及到委托.下面代码包括自定义事件从事件定义到事件触发和执行的全过程. using System; using System.Collections.Generic; ...

  2. 字符集详解 ------------------------ UNICODE +UTF8

    http://my.oschina.net/goldenshaw/blog?catalog=3294521 http://my.oschina.net/goldenshaw/blog?catalog= ...

  3. Linux多网卡多IP配置

    echo "210 local100" >> /etc/iproute2/rt_tables echo "220 local200" >> ...

  4. 高性能爬虫为什么使用定制DNS客户端?

    DNS 解析是高性能网络爬虫的瓶颈,主要是因为: 1. 由于域名服务的分布式的特性,DNS解析可能需要多次的请求转发,有时需要几秒甚至更长的时间来解析出相应的IP 地址. 2. 现有的标准库对DNS解 ...

  5. JavaScript 应用开发 #2:视图与模板

    在用 Backbone 开发的 JavaScript 应用里面,除了模型与集合以外,另一个重要的部分就是视图,英文是 View .在视图里面,我们可以去监听在页面上发生的事件,还有与视图相关的模型和集 ...

  6. MegaCli监控RAID磁盘健康信息

    首先有必要先介绍一下有关RAID卡的使用,有关Cache问题也有个人理解:生产系统上的物理机磁盘配置大多都是RAID5,之前会经常性的遇到磁盘IO在某个时间极度的跟不上节奏,稍微写入量,磁盘utils ...

  7. mysql 1067 进程意外终止 无法启动

    查看日志 data/XXX.err 发现如下错误 [ERROR] InnoDB: Attempted to open a previously opened tablespace. Previous ...

  8. app抓包

    http://www.360doc.com/content/14/1126/11/9200790_428168701.shtml 记得下载证书  不然有些网站是抓不到的

  9. javaBean登录注册

    package javabean; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.Res ...

  10. java-字符串学习总结

    Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类. String 类相关基础认知: 1.String类是final的,不可被继承.public fin ...