main文件:
#include "BM.h"
//BF算法(朴素模式匹配算法):时间复杂度O(strlen(src)*strlen(dest)), 空间复杂度O(1)
//KMP:时间复杂度O(strlen(src)+strlen(dest)), 空间复杂度O(strlen(dest))
//BM :时间复杂度最好O(strlen(src)/strlen(dest)), 最坏O(strlen(src)*strlen(dest)), 空间复杂度:建表占用空间
int main()
{
char *src = "bbbbshfdsdhfhsadfsdahghfsadfsahdfsbdfsdfsdfsdsdfsdfsdaf";
char *dest = "bdfsdfsdfsd";//bdfsdfsdfsd
printf("src = %s\n", src);
printf("dest = %s\n", dest);
//-----------test bad_char---------------//
//int loc = match_by_bad_char(src, dest); //最坏自符表
//printf("loc = %d\n", loc);
//-----------test good suffix------------//
//int loc = mathc_by_good_suffix(src, dest);//最好后缀表
//printf("loc = %d\n", loc);
//-----------test BM---------------------//
int loc = match_by_BM(src, dest);
printf("\n\nthe match loc = %d\n", loc);
system("pause");
return 0;
}
BM.h文件
#pragma once
#include <cstdio>
#include <cstdlib>
#include <cstring>
void build_bad_char_shift(const char *str, int *shift);
void bulid_good_suffix_shift(char *str, int *shift);
int match_by_bad_char(const char *src, const char *dest);
int mathc_by_good_suffix(const char *src, char *dest);
int match_by_BM(char *src, char *dest);
/***********************************************************************/
//FUNCTION:建立坏字符表
void build_bad_char_shift(const char *str, int *shift)
{
int len = strlen(str);
for (int i = 0; i < 256; i++)
shift[i] = len;
for (int j = len-1; j >=0; j--)
shift[(unsigned char)*str++] = j;
}
/***********************************************************************/
//FUNCTION:应用坏字符表匹配模式串
int match_by_bad_char(const char *src, const char *dest)
{
int len_src = strlen(src);
int len_dest = strlen(dest);
if (len_dest > len_src)
return -1;
int *shift = (int *)malloc(sizeof(int)*256);
build_bad_char_shift(dest, shift);
int tride = len_dest;
int s_id = len_dest;
while (s_id <= len_src)
{
int d_id = len_dest;
while (src[--s_id] == dest[--d_id])
{
if (d_id == 0)
return s_id;
}
tride = shift[(unsigned char)src[s_id]];
printf("s_id = %d\n", s_id);
s_id += (tride > len_dest-d_id ? tride : len_dest-d_id) + 1;
printf("s_id = %d\n", s_id);
}
free(shift);
shift = NULL;
return -1;
}
/***********************************************************************/
//FUNCTION:建立最好后缀字符表
void bulid_good_suffix_shift(char *str, int *shift)
{
int len = strlen(str);
shift[len-1] = 1;
char *p_now = str+len-2;
char *p_prev, *p_next, *p_temp;
char ch = str[len-1];
int delta_len; //应该移动的字符数
for (int i = len-2; i >= 0; i--, p_now--)
{
p_temp = str+len-2;
while (true)
{
while (p_temp >= str && *p_temp-- != ch);
p_prev = p_temp;
p_next = str+len-2;
if (p_prev < str && *(p_temp+1) != ch) //寻找子串失败
{
delta_len = len;
break;
}
bool match_flag = true;
while (p_prev >= str && p_next > p_now)
{
if (*p_prev-- != *p_next--)
{
match_flag = false;
break;
}
}
if (!match_flag) //继续往前寻找
continue;
else
{
if (p_prev < str || *p_prev != *p_next)
{
delta_len = p_next - p_prev;
break;
}
}
}//while
shift[i] = len-i + delta_len - 1;
}//for
}
/***********************************************************************/
//FUNCTION::应用好后缀表匹配模式串
int mathc_by_good_suffix(char *src, char *dest)
{
int len_src = strlen(src);
int len_dest = strlen(dest);
if (len_dest > len_src)
return -1;
int *shift = (int *)malloc(sizeof(int)*len_dest);
bulid_good_suffix_shift(dest, shift);
for (int s = 0; s < len_dest; s++)
printf("shift[%d] = %d\n", s, shift[s]);
int s_id = len_dest;
while (s_id <= len_src)
{
int d_id = len_dest;
while (src[--s_id] == dest[--d_id])
{
if (d_id == 0)
return s_id;
}
s_id += shift[d_id] + 1;
}
free(shift);
shift = NULL;
return -1;
}
/***********************************************************************/
//FUNCTION:
int match_by_BM(char *src, char *dest)
{
int len_src = strlen(src);
int len_dest = strlen(dest);
if (len_dest > len_src)
return -1;
int *shift_bad_char = (int *)malloc(sizeof(int)*256);
build_bad_char_shift(dest, shift_bad_char);
int *shift_good_suffix = (int *)malloc(sizeof(int)*len_dest);
bulid_good_suffix_shift(dest, shift_good_suffix);
printf("\nthe shift_bad_char array : \n");
for (int s = 0 ; s < len_dest; s++)
printf("s[%d] = %d\t", s, shift_bad_char[(unsigned char)dest[s]]);
printf("\n\nthe shift_good_suffix array : \n");
for (int s = 0; s < len_dest; s++)
printf("s[%d] = %d\t", s, shift_good_suffix[s]);
int s_id = len_dest-1;
while (s_id <= len_src)
{
int d_id = len_dest-1;
while (d_id > 0 && src[s_id] == dest[d_id])
{
s_id--;
d_id--;
}
if (d_id == 0)
return s_id;
int tride_bad_char = shift_bad_char[(unsigned char)dest[d_id]];
int tride_good_suffix = shift_good_suffix[d_id];
s_id += tride_bad_char > tride_good_suffix ? tride_bad_char : tride_good_suffix;
}
free(shift_bad_char);
shift_bad_char = NULL;
free(shift_good_suffix);
shift_good_suffix = NULL;
return -1;
}