C++BM算法

BM算法是一种非常著名的字符串查找算法:

在字符串查找算法中,最著名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore)。两个算法在最坏情况下均具有线性的查找时间。但是在实用上,KMP算法并不比最简单的c库函数strstr()快多少,而BM算法则往往比KMP算法快上3-5倍。

下面我们介绍一下BM算法:

1,BM算法是Boyer-Moore算法的简称,由Boyer 和Moore提出. 

2,BM算法也是一种快速串匹配算法,BM算法与KMP算法的主要区别是匹配操作的方向不同。虽然BM算法仅把匹配操作的字符比较顺序改为从右向左,但匹配发生失败时,模式T右移的计算方法却发生了较大的变化. 

3,滑动距离函数: 
为方便讨论,BM算法的关键是,对给定的模式T="t0t1…tm"定义一个从字符到正整数的映射: 
dist :c->{1,2,…,m+1} 
函数dist称为滑动距离函数,它给出了正文中可能出现的任意字符在模式中的位置。函数dist定义如下: 
dist(c) = m-j  j为c在模式中的下标,以后面的为准 
dist(c) = m+1  若c不在模式中或c = tm 
例如,T="pattern",则dist(p)= 6 – 0 = 6, dist(a)= 6 – 1 =5, dist(t)=
6 – 3 =3,dist(e)= 2, dist(r)= 1, dist(n)= 6 + 1 = 7。 

4,BM算法的基本思想是:假设将主串中自位置i起往左的一个子串与模式进行从右到左的匹配过程中,若发现不匹配,则下次应从主串的i + dist(si)位置开始重新进行新一轮的匹配,其效果相当于把模式和主串向右滑过一段距离dist(si),即跳过dist(si)个字符而无需进行比较。 

如这样一个例子:


从FINDINAHAYSTACKNEEDLEINA中查找NEEDLE的过程:

i    j    00    01    02    03    04    05    06    07    08    09    10    11    12     13    14    15    16    17    18    19
   20    21    22    23

          F      I       N      D     I      N    
A      H     A      Y    S      T      A       C     K      N    E      E
    D      L     E
     I       N      A

0   5   N     E      E      D     L       E

5   5                                           N     E      E      D     L      E

11 4                                                                                           N       E       E     D    L
    E

15 0                                                                                                                             N
    E      E     D     L     E

排版不是很好排,请大家见谅

第一步:i=5,j=5失败 dist(N)= 5 所以右移到5+5=10处

第二步:i=10,j=5失败 无dist(S) 所以右移到10+6 =16处

第三步:i=15,j=4失败 dist(N) = 5 所以右移到15+5 = 20处匹配成功

实例代码: 

#include <iostream>
#include <cstring>
using namespace std;

int Dist(char *t,char ch)
{
    int len = strlen(t);
    int i = len - 1;
    if(ch == t[i])
      return len;
    i--;
    while(i >= 0)
    {
      if(ch == t[i])
         return len - 1 - i;
      else
         i--;
    }
    return len;
}

int BM(char *s,char *t)
{
    int n = strlen(s);
    int m = strlen(t);
    int i = m-1;
    int j = m-1;
    while(j>=0 && i<n)
    {
    if(s[i] == t[j])
    {
        i--;
        j--;
    }
    else
    {
        i += Dist(t,s[i]);
        j = m-1;
    }
    }
    if(j < 0)
    {
        return i+1;
    }
    return -1;
}

int main()
{
    char p1[]="substring searching algorithm search";
    char p2[]="search";
    cout<<BM(p1,p2);
    return 0;
}


时间: 2024-10-09 11:52:51

C++BM算法的相关文章

大话数据结构十二:字符串的模式匹配(BM算法)

1. BM算法简介: KMP算法其实并不是效率最高的字符串匹配算法,实际应用的并不多,各种文本编辑器的"查找"功能大多采用的是BM算法(Boyer Moore).BM算法效率更高,更容易理解. 2. BM算法分析: (1) 假定字符串为"HERE IS A SIMPLE EXAMPLE",搜索词为"EXAMPLE". (2) 首先,"字符串"与"搜索词"头部对齐,从尾部开始比较.这是一个很聪明的想法,因为如

C++ SUNDY算法(BM算法的改进)

字符串查找算法中,最著名的两个是KMP算法Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情 况下均具有线性的查找时间.BM算法往往比KMP算法快上3-5倍.但是BM算法还不是最快的算法,这里介绍一种比BM算法更快一些的查找算法. 例如我们要在"substringsearchingalgorithm"查找"search" 第一步,把子串与文本左边对齐: s u b s t r i n g s e a r c h i n g

bm算法-模式匹配中的BM算法的C语言源代码

问题描述 模式匹配中的BM算法的C语言源代码 用c实现BM算法,匹配字符串和匹配文本都是手动输入,然后输出是否在匹配文本中找到匹配字符串,结果一定要正确没bug.

OpenCV stereo matching BM 算法

  一直找不到opencv stereo matching的根据和原理出处,下面这个文章贴了个链接,有时间看看:     Basically OpenCV provides 2 methods to calculate a dense disparity map: cvFindStereoCorrespondenceBM: Fast (can process several images per second), but if parameters not tuned then the resu

JavaScript中数据结构与算法(四):串(BF)

  这篇文章主要介绍了JavaScript中数据结构与算法(四):串(BF),串是由零个或多个字符组成的有限序列,又叫做字符串,本文着重讲解了BF(Brute Force)算法,需要的朋友可以参考下 串是由零个或多个字符组成的有限序列,又叫做字符串 串的逻辑结构和线性表很相似的,不同的是串针对是是字符集,所以在操作上与线性表还是有很大区别的.线性表更关注的是单个元素的操作CURD,串则是关注查找子串的位置,替换等操作. 当然不同的高级语言对串的基本操作都有不同的定义方法,但是总的来说操作的本质都

JavaScript中数据结构与算法(五):经典KMP算法

  这篇文章主要介绍了JavaScript中数据结构与算法(五):经典KMP算法,本文详解了KMP算法的方方面在,需要的朋友可以参考下 KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配是指:模式串和母串的的比较从右到左,模式串的移动从左到右. 通过上一章显而易见BF算法也是属于前缀的算法,不过就非常霸蛮的逐个匹配的效率自然不用提了O(mn),网上

JAVA实现KMP算法理论和示例代码_java

一.理论准备KMP算法为什么比传统的字符串匹配算法快?KMP算法是通过分析模式串,预先计算每个位置发生不匹配的时候,可以省去重新匹配的的字符个数.整理出来发到一个next数组, 然后进行比较,这样可以避免字串的回溯,模式串中部分结果还可以复用,减少了循环次数,提高匹配效率.通俗的说就是KMP算法主要利用模式串某些字符与模式串开头位置的字符一样避免这些位置的重复比较的.例如 主串: abcabcabcabed ,模式串:abcabed.当比较到模式串'e'字符时不同的时候完全没有必要从模式串开始位

字符串搜索-Boyer-Moore算法 《数据结构与算法c++版》Adam Drozdek

问题描述 Boyer-Moore算法 <数据结构与算法c++版>Adam Drozdek 通常BM算法采用的是坏字符和好后缀算法(eg.,BM算法),我学习的<数据结构与算法c++版>Adam Drozdek版教材上使用了 全后缀和部分后缀规则,这种方法在网络上基本查不到. 作者解释原理时,一个关键的函数只是给出公式,基本上没有解释,如下: 请问怎么理解这个公式,尤其是公式中的s代表什么意思? 原书我已经在云盘共享,关于BM算法书上在P687面.希望能帮忙解决.

算法在身边——学习算法从妈妈的菜谱开始

听到"算法(Algorithm)"这个词,大部分人都觉得好像很艰深晦涩.的确,这不是一个常常能听到的词.事实上,在数学.计算机等理工科领域,所谓的算法,指的就是"对特定问题的解决步骤".而这里说的特定问题,通常有: • 对信息进行排序 • 搜索目标信息 等不同的问题. 此外,如果说"算法是解决问题的步骤",那么撇开计算机的数据处理不论,现实生活中也有很多问题的解决方法蕴含了算法的思想.这其中的代表就是菜谱. 我们都知道,记录做出各色各样的菜品所需