BM字符串匹配算法

/**
* @file string_BM.cpp
* @author Invisiphatom (ethancao16770@gmail.com)
* @brief BM algorithm
* @version 0.1
* @date 2023-04-12
*
* @copyright Copyright (c) 2023 Invisiphatom
* All Rights Reserved.
*
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int TABLE_SIZE = 256; // set string's ANSIC range
int get_suffix_len(const string P, const int end) {
int suffix_end = P.size() - 1;
int midstr_end = end;
int suffix_len = 0;
while (midstr_end >= 0 && P[midstr_end] == P[suffix_end]) {
suffix_len++;
midstr_end--;
suffix_end--;
}
return suffix_len;
}
bool judge_is_prefix(const string P, const int start) {
int prefix_start = 0;
int midstr_start = start;
while (midstr_start < P.size()) {
if (P[midstr_start] != P[prefix_start]) return false;
midstr_start++;
prefix_start++;
}
return true;
}
vector<int> build_bad_table(const string P) {
vector<int> bad_table(TABLE_SIZE, P.size());
// NOTE {P.size() - 1} -> The last element is excluded
for (int pi = 0; pi < P.size() - 1; pi++)
bad_table[P[pi]] = P.size() - (pi + 1);
return bad_table;
}
vector<int> build_good_table(const string P) {
vector<int> good_table(P.size(), 0);
for (int pi = P.size() - 1, match_len = 0; pi != 0; pi--) {
// reset match_len dynamically according to different pi
if (judge_is_prefix(P, pi)) match_len = P.size() - (pi + 1);
// (P.size() + (P.size() - (pi + 1))) -> 过度滑动, match_len -> 缓解过度滑动
good_table[pi - 1] = (P.size() + (P.size() - (pi + 1))) - match_len;
}
// 顺序扫描,将中间字符串与相应后缀之间配对起来
// NOTE {P.size() - 1} -> The last element is excluded
for (int pi = 0; pi < P.size() - 1; pi++) {
int suffix_len = get_suffix_len(P, pi);
if (suffix_len != 0)
good_table[P.size() - 1 - suffix_len] = P.size() - (pi - suffix_len + 1);
}
return good_table;
}
void BM_matcher(const string T, const string P) {
if (P.size() > T.size()) return;
auto bad_table = build_bad_table(P);
auto good_table = build_good_table(P);
auto ti = P.size() - 1;
auto pi = P.size() - 1;
while (ti < T.size()) {
while (T[ti] == P[pi]) {
if (pi == 0) {
cout << "Match in position: " << ti << endl;
break;
}
ti--;
pi--;
}
ti += max(bad_table[T[ti]], good_table[pi]);
pi = P.size() - 1;
}
}
int main() {
string T = "HERE IS A SIMPLE EXAMPLE";
string P = "EXAMPLE";
BM_matcher(T, P);
return 0;
}

image
image

参考文章:

不用找了,学习BM算法,这篇就够了(思路+详注代码)-CSDN博客

字符串匹配算法(二):BM(BoyerMoore)算法、坏字符规则,好后缀规则_bm坏字符规则-CSDN博客

posted @   残影0无痕  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示