今天来复习下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
转载:http://zuowenp.blogbus.com/logs/85068992.html