讲师中心 微信公众号
AI工具推荐 视频效率加速

C++实现字符串匹配的Boyer-Moore算法 _ 坏字符与好后缀规则【源码】

陌伟酱_3589

陌伟酱_3589

发布时间:2026-04-10 21:54:33

|

1033人浏览过

|

来源于php中文网

原创

Boyer-Moore坏字符表须用unsigned char作下标,vector大小256初值-1;好后缀suffix[i]表示以i结尾的后缀匹配真后缀的最大长度,prefix[i]标记是否为border;位移取bad_shift与good_shift最大值且至少为1。

c++实现字符串匹配的boyer-moore算法 _ 坏字符与好后缀规则【源码】

Boyer-Moore 的 bad_char_shift 表怎么建才不越界?

建表本质是为每个字符预存「若失配,模式串该右移多少位」,但 C++ 中 std::string::at() 或数组索引容易因字符值超出 0–255 范围而崩——尤其用 char 当数组下标时,负值会转成巨大正索引。必须统一用 unsigned char 做键。

实操建议:

立即学习“C++免费学习笔记(深入)”;

  • 用 std::vector<int></int>(大小 256)初始化全为 -1,表示该字符在模式串中未出现
  • 遍历模式串 pattern 时,对每个位置 j,执行 bad_char[static_cast<unsigned char>(pattern[j])] = j</unsigned>
  • 查表时也必须 static_cast<unsigned char>(text[i])</unsigned>,否则 ASCII 扩展字符或 locale 相关字符会错位
  • 别用 map<char int></char>——常数大、缓存不友好,BM 对性能敏感

好后缀规则的 suffix 和 prefix 数组怎么填?

这是最容易写反的地方:suffix[i] 表示「以 i 结尾的后缀」能与模式串某个真后缀匹配的最大长度,不是从开头匹配;而 prefix[i] 标记该后缀是否恰好匹配模式串开头(即是否为 border)。很多人误把 i 当作起始位置。

实操建议:

立即学习“C++免费学习笔记(深入)”;

  • 倒序构建:i 从 len - 2 到 0(最后一个字符的后缀长度为 0,跳过)
  • 对每个 i,设 len_suffix = 0,然后从末尾向前比对:只要 pattern[j] == pattern[i + (len - 1 - j)] 就累加 len_suffix,直到失配
  • prefix[i] 只需检查 suffix[i] == len - i 是否成立——即匹配长度刚好撑满从 i 到末尾的区间
  • 别漏掉边界:当整个后缀匹配模式串前缀时(i == 0),prefix[0] 必须为 true,否则后缀规则在首字符失配时无法触发最大位移

主循环里,坏字符和好后缀位移量怎么取 max?

Boyer-Moore 正确性依赖「取两者位移中的较大值」,但新手常写成 shift = std::max(bad_shift, good_shift) 后直接跳,却忘了:如果 good_shift 为 0(比如后缀完全不匹配且无 border),而 bad_shift 算出来是负数或 0,就会死循环。

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载

实操建议:

立即学习“C++免费学习笔记(深入)”;

  • bad_shift 计算为 i - bad_char[...],若结果 ≤ 0,说明坏字符在模式串中位置 ≥ 当前比较点,此时按规则应至少右移 1 位——所以强制 bad_shift = std::max(1, i - bad_char[...])
  • good_shift 来自两个分支:若存在等长后缀(suffix[i] > 0),则位移为 len - suffix[i];否则找最长 border(prefix[j] 为 true 的最小 j > i),位移为 len - j;都找不到就退化为 len
  • 最终 shift = std::max(bad_shift, good_shift),但必须确保 shift >= 1,否则加一句 shift = std::max(shift, 1)

为什么在短模式串(

预处理开销固定:坏字符表要扫一遍模式串,好后缀表要 O(m²) 构建(标准实现)或 O(m) 但代码复杂。当 m 很小时,这部分时间占比压倒主循环节省的比较次数。

实操建议:

立即学习“C++免费学习笔记(深入)”;

  • 实际工程中,通常设阈值(如 m )直接切回 <code>std::string::find() 或手写朴素匹配
  • 不要盲目套用 BM——它真正优势在长模式串(> 15 字符)+ 高熵文本(如源码、日志),此时坏字符跳过大量位置
  • 如果文本含大量重复字符(如 DNA 序列),好后缀规则收益下降,坏字符表又可能退化(多数字符相同),这时要考虑 Shift-And 或 AC 自动机

C++ 实现 BM 最容易被忽略的,其实是字符类型转换的一致性——一个 char 没 cast 成 unsigned char,整张坏字符表就全偏了;而好后缀表里 prefix 数组若没正确标记 i==0 的情况,会导致首次失配只挪 1 位,彻底失去 BM 的加速意义。

热门AI工具

更多
Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

5939

2023.08.02

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1658

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2504

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

5964

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

5349

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

7054

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

10014

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

5099

2025.07.29

PixTV官网入口地址合集
PixTV官网入口地址合集

本专题汇总了 PixTV AI 一站式视频创作平台的官方入口与使用教程。无需下载软件,浏览器直接访问即可使用。平台将剧本、图像、视频、声音与剪辑整合在“无限画布”中,接入 GPT Image 2.5、Seedance 2.5 等头部模型。本专题整理了从新建画布、角色锚定、分镜拆分到视频生成与导出的完整操作指南,助你快速上手 AI 短剧与漫剧创作。

20

2026.10.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn