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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本