BM算法

来源:互联网 发布:机场安检 知乎 编辑:程序博客网 时间:2024/05/16 01:42

BM算法

版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://www.blogbus.com/zuowenp-logs/85068992.html

今天来复习下BM算法。

Boyer-Moore算法,简称BM算法,是一种快速查找字符串的方法。时间复杂度为O(m/n),其中m为要查找的文本长度,n为要在文本中查找的字符串长度,在最坏的情况下,也具有线性的性能。

BM算法是通过跳过字符+回溯来快速匹配字符串的,我说下我对BM算法的理解。

BM算法是从右边最后一个字母开始进行匹配的。假如在I would love to change the world中查找world单词

I would love to change the world
world

先从单词最右开始,匹配u和world,发现u不在world中,那么world肯定不能在u之前的5个字母中匹配,于是假设在下5个字母匹配,向前跳一个单词的长度。

I would love to change the world.
     world

继续从最右进行匹配,我们发现o虽然不和d匹配,但是和world的第二个字母o匹配,于是假设文本的o就是我们要匹配单词中的o,进行对齐。

I would love to change the world.
        world 
 

仍然从右匹配,发现空格不在world中,那么继续跳一个单词的长度。

I would love to change the world.
             world  

h也不在world中,继续跳一个单词的长度。

I would love to change the world.
                  world  

仍然无匹配,继续跳一个单词。 

I would love to ch ange the world.
                        world

我们发现w和world中第一个字母匹配,于是对齐。 

I would love to ch ange the world.
                            world

从右开始匹配d到w都相等,于是匹配成功。

文本长度为33,要匹配的字符串长度5,整个过程匹配了7次,复杂度O(33/5)接近于7。

下面是实现代码

#include
#include
#define MAX_CHAR 256

using namespace std;
char *BM(char *text,char *str,int textlength)
{
        unsigned int Jump[MAX_CHAR];
        char *str_end;
        int strlength=0;
        strlength=strlen(str);
        for(int i=0;i != MAX_CHAR-1;i++)
        {Jump[i]=strlength;}


        str_end = str;
        for(int num = 1;*(str_end+1);num++)
        {
                Jump[(unsigned char)*str_end]=strlength-num;
                str_end++;
        }
       
        int utxt=strlength-1;
        int uPat=strlength;
        while(utxt < textlength && uPat != 0)
        {
                if(text[utxt] == str[uPat-1])
                {
                utxt--;
                uPat--;
                }
                else
                {
                utxt=utxt+Jump[(unsigned char)text[utxt]];
                uPat=strlength;
                }
        }

        if(uPat==0)
        {
        return (char*)(text+utxt+1);
        }
        else
        {return NULL;}
}

实现思路是:建一个数组来实现跳转,如果匹配的字母在字符串中,则跳相应的长度,不在则跳字符串的长度。

 

int main()
{
char a[]="Welcome to my blog zuowenp.blogbus.com";
char b[]="blog";
cout<<(char *)BM(a,b,19);

return 0;
}

输出blogbus.com

0 0