Skip to content

2019年 408 数据结构 第 9 题

数据结构2019年选择题2分

题目

设主串 T="abaabaabcabaabc",模式串 S="abaabc",采用 KMP 算法进行模式匹配,到匹配成功时为止,在匹配过程中进行的单个字符间的比较次数是( )。

错因

A

漏算了"失配"那一次比较。匹配跟踪时只把成功匹配的字符比较计数,把 那次"失败"看成 j 直接跳转、不算字符比较,于是少了 1 次得到 9。但失配的字符比较本身是真实发生的字符比较,必须计入。

C

把 j 回退动作也错算成额外的字符比较。例如认为 从 5 回退到 2 的过程中"重新对齐"会涉及多个字符比较,结果多算 2 次。其实 是查表跳转,不进行字符比较,回退后才在新位置进行 1 次新比较。

D

完全按朴素模式匹配(BF 算法)的方式计算:每次失配把主串指针 i 也回退到 i−j+1 起点重新匹配,整体比较次数接近 的量级。但题目明说用 KMP,KMP 的核心优势就是主串指针 i 永不回退,比较次数远少于 BF。

总解析

步骤 1:求模式串 S = "abaabc" 的 next 数组(next[j] = S[0..j−1] 的最长真前缀=真后缀长度)

jS[0..j−1]最长前后缀公共长度next[j]
0""00
1"a"00
2"ab"00
3"aba""a"="a",长度 11
4"abaa""a"="a",长度 11
5"abaab""ab"="ab",长度 22

步骤 2:跟踪匹配过程(i 是主串指针,j 是模式指针;每次" vs "算 1 次比较)

ijT[i]S[j]结果累计比较
100aa匹配 → i++, j++1
211bb匹配2
322aa匹配3
433aa匹配4
544bb匹配5
655ac失配 → j=next[5]=2,i 不动6
752aa匹配7
863aa匹配8
974bb匹配9
1085cc匹配 → j+1=6=|S|,匹配成功10

关键观察

  • 第 6 步是失配但仍算 1 次比较("=a vs =c"是一次真实的字符比较,不能因为结果是"不等"就漏算)。
  • 从 5 回退到 2 是查 next 表的跳转,不进行字符比较
  • 之后第 7 步是 的全新比较——主串位置没动,但模式位置变了,是新的 1 次。

总比较次数 = 10。最终答案是 B

最后更新:

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

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