Skip to content

2024年 408 数据结构 第 6 题

数据结构2024年选择题2分

题目

KMP 算法使用修正后的 next 数组进行模式匹配,模式串 S = "aabaab",当主串中某字符与 S 中某字符失去配对时,S 将向右滑动的最长距离是( )

错因

B

把 nextval 表算错了一项:在 j=5 处误判 P[5]='a' 与 P[next[5]]=P[2]='a' "不相等",结果 nextval[5] 留成了 next[5]=2 而不是继续递归到 0,得 5−2=3 或干脆把 j=4/j=6 处的 4 当成最大值,没继续比到 j=5 的 5。漏检了 nextval 修正传播这一步。

C

完全没用"修正后的 next",直接用了原始 next 数组

j123456
next[j]012123
j − next[j]111333

得到最大滑动距离 = 3,但题目明确要求"修正后的 next 数组"——nextval 比 next 滑得更远,因为它把"用前缀重新匹配后还会立刻失配"那些无效尝试一并跳过。看错题干关键词。

D

按"模式串里最长重复前缀"目测:注意到 "aabaab" 里 "aab" 重复了一次,于是认为模式串只需要滑动到第二个 "aab" 的位置(滑 3 位);又或者把"成功匹配整串后的下一次起点"当成"失配滑动距离",把 m − 最长公共前后缀长度(6−4=2)当成答案。这个思路适用于"完全匹配后继续找下一次出现",与失配时的滑动距离没有关系

总解析

KMP "修正后的 next" 常指 nextval——即在 next 的基础上消除无效比较的优化版本。算这道题分三步。

Step 1:算原始 next(next[j] = 最长真前后缀公共长度 + 1)

j123456
P[j]aabaab
next[j]012123

Step 2:修正为 nextval(若 ,则 ;否则

jP[j]next[j]P[next[j]]相等?nextval[j]
1a00
2a1anextval[1] = 0
3b2a2
4a1anextval[1] = 0
5a2anextval[2] = 0
6b3bnextval[3] = 2

所以 nextval = [0, 0, 2, 0, 0, 2]

Step 3:算每个 j 处的滑动距离 = j − nextval[j]

j123456
j − nextval[j]121454

最大滑动距离 = 5,发生在 j=5(即模式串第 5 个字符与主串失配时)。

直观理解为什么是 5:j=5 意味着已经成功匹配 "aaba",第 5 位 P[5]='a' 失配。如果用普通 next,next[5]=2 会建议"从 P[2] 开始再比",但 P[2]='a' 与刚才失配的主串字符还是 'a'——一定再次失配,浪费一次比较。nextval 把这种"注定会再失配"的尝试一并跳过,递归到 nextval[2]=0,等于让模式串整体从头开始匹配,相对主串滑了 5 位。

最终答案是 A(5)

最后更新:

🎬 可视化演示
加载中...

提示:可在可视化区直接操作播放、步进、修改参数