蛮力匹配
看完你能逐字符推演暴力匹配全过程,并说清它为何慢、何时够用
按 空格/→ 演示下一步
全部页面点击任意一页,跳回舞台从这页播放
蛮力匹配
看完你能逐字符推演暴力匹配全过程,并说清它为何慢、何时够用
什么是串匹配
上一页我们把蛮力匹配的代码跑了一遍。在拆解它为什么慢之前,得先把问题本身说清楚:所谓串匹配,到底在主串里找什么、找到哪一步才算找到?
钥匙对准锁孔是对齐位置,能否拧动是匹配判定
蛮力法的构思
前页说了:串匹配就是在长文里找短词的位置。那最直接的办法是什么?把短词按在长文的开头,一位一位比对,不行就换个位置再按一次——这就是蛮力法。
钥匙插进锁孔逐齿比对,齿形不对就拔出来换一把再插
对齐与移动的全景
图示主串、模式串、对齐位置的关系
版本一:从右向左比对
在每个对齐位置,从模式串末字符开始、从右向左逐个比对。
版本一代码
版本一的完整实现:把上一页的比对逻辑落成可运行代码,逐行看清从右向左的策略。
第 5 行确定最多 n-m+1 次对齐;第 7 行把指针从 m-1 起从右向左走;第 9 行是失败短路——一旦失配立刻停止本轮;第 13 行验证真实输出。
版本二:从左向右比对
换一种思路:对齐后从最左字符开始比,一旦失配立即停下。
版本二代码
从左向右比对的蛮力匹配实现:逐行读循环与边界,看清移位逻辑藏在哪一行为。
range(n-m+1) 保证最后 m 个字符也对齐;T[i+j] 同时表达「对齐 i」与「从左向右推进 j」;j==m 才是匹配成功,而非相等本身。
版本一 vs 版本二
两个版本只是比对方向相反,细节差异却常被忽略——它们是否真的等价?
- 从模式串末字符开始比对
- 主串指针可整体回退,最坏 O(mn)
- 坏消息来得晚,发现失配前匹配了更多字符
- 从模式串首字符开始比对
- 同样逐窗口移动,最坏仍 O(mn)
- 坏消息来得早,首个字符即失配可快速换位
最好情况
前面看到版本一比版本二平均更快。但真正的差距在极端情况下更悬殊:有时每次比对只要一眼就能断定失败,有时一次对齐就全部命中——这时两版都退化为最省事的线性扫描。
翻一张就发现不对,直接翻下一张,不必翻完整副
最坏情况
上一页看到最好情况一次就中,但运气不会天天好。最倒霉的时刻是:每一轮都对到最后一个字符才宣告失败,前面 m-1 次比对全白费。
每次翻到最后一个字母才发现不对,只能翻下一页重来
自测
蛮力匹配中,一次比对失败后,模式串相对文本串移动多少位?
小结
- ✓匹配失败时的移动量决定整体效率
- ✓比对方向影响的是常数,不改变 O(mn) 上界
- ✓最好与最坏情况差距可达线性 vs 平方
- ✓正确但慢,正是它成为一切改进的基线
- ✓优化方向:失败后利用已比对的信息多移几步
课后思考
先自己想几分钟,再对照参考答案——开放问题没有唯一解。
参考答案从「每次失配只挪一格、不做任何记忆」入手:方向只是表象,本质是失败后信息全丢,主串指针回退,导致重复比对。
参考答案实际场景中模式短、字母表大、失配早、随机数据期望接近 O(n+m),实现简单缓存友好;工程上是「够用且稳」,值得从成本收益角度想。
参考答案字母表越小,随机失配越晚、伪命中越多,期望性能越差;这提示复杂度不只看 n、m,还和字符集大小 σ 有关。