4.4模式匹配-BM算法
类似于KMP算法,遵从“坏字符、好后缀”规则。
(1)BM算法来历
1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法:Boyer-Moore算法,简称BM算法。该算法从模式串的尾部开始匹配,且拥有在最坏情况下O(N)的时间复杂度。在实践中,比KMP算法的实际效能高。
(2)BM算法
int BM(char *x, char *y)
{
int m;//模式串的长度
int n;//目标串的长度
int i;//模式串中匹配的位置
int j;//目标串中匹配的位置
int bmGs[XSIZE];//好后缀表
int bmBc[ASIZE];//坏字符表
preBmBc(x, bmBc);
preBmGs(x, bmGs);
m = strlen(x);
n = strlen(y);
j=0;
while (j < n-m )
{
for (i = m - 1; i >= 0 && x[i] == y[i + j]; --i);
if (i < 0)
{
return j;
}
else
{
j += (bmGs[i]) > (bmBc[y[i+j]] -m + 1 +i) ? (bmGs[i]) : (bmBc[y[i+j]] -m + 1 +i);
}
}
if (j >= n-m)
{
return -1;
}
}
(3)模式匹配
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
#define XSIZE 8
#define ASIZE 256
void preBmBc(char *x, int bmBc[]);
void preBmGs(char *x, int bmGs[]);
void suffixes(char *x, int *suff);
int BM(char *x, char *y);
void main()
{
char x[100];
char y[100];
int location;
printf("input string patter:\n");
gets(y); gets(x);
location = BM(x, y);
printf("\n模式串在目标串中出现的位置是:%d\n",location+1);
}
int BM(char *x, char *y)
{
int m;//模式串的长度
int n;//目标串的长度
int i;//模式串中匹配的位置
int j;//目标串中匹配的位置
int bmGs[XSIZE];//好后缀表
int bmBc[ASIZE];//坏字符表
preBmBc(x, bmBc);
preBmGs(x, bmGs);
m = strlen(x);
n = strlen(y);
j=0;
while (j < n-m )
{
for (i = m - 1; i >= 0 && x[i] == y[i + j]; --i);
if (i < 0)
{
return j;
}
else
{
j += (bmGs[i]) > (bmBc[y[i+j]] -m + 1 +i) ? (bmGs[i]) : (bmBc[y[i+j]] -m + 1 +i);
}
}
if (j >= n-m)
{
return -1;
}
}
void preBmBc(char *x, int bmBc[])
{
int m;
int i;
m = strlen(x);
for (i = 0; i < ASIZE; i++)
{
bmBc[i]=m;
}
for (i = 0; i < m - 1; i++)
{
bmBc[x[i]] = m-1-i;
}
}
void suffixes(char *x, int *suff)
{
int i;
int f;
int g;
int m;
m = strlen(x);
f = 0;
suff[m-1] = m;
g = m - 1;
for (i = m - 2; i >= 0; --i)
{
if (i > g && suff[(m-1)-(f-i)] < i - g)
{
suff[i] = suff[(m-1)-(f-i)];
}
else
{
if (i < g)
g=i;
f=i;
while (g >= 0 && x[g] == x[g + m - 1 -f])
{
g--;
}
suff[i] = f - g;
}
}
for (i = 0; i < m; i++)
{
printf("%d ",suff[i]);
}
printf("\n");
}
void preBmGs(char *x, int bmGs[])
{
int i;
int j;
int suff[XSIZE];
int m;
m=strlen(x);
suffixes(x, suff);
for (i = 0; i < m; ++i)
{
bmGs[i] = m;
}
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;
}
}
}
}
for (i = 0; i <= m-2; ++i)
{
bmGs[m - 1 -suff[i]]= m - 1 - i;
}
for (i = 0; i < m; i++)
{
printf("%d ",bmGs[i]);
}
printf("\n");
}