408模拟选择题 · 数据结构 · 第4章 串
4.2 串的模式匹配
4.2.2 串的模式匹配算法——KMP算法
- 【王道·卷六-Q04】 在使用KMP算法进行模式匹配的过程中,如果某趟匹配失败,i指示主串中失配的位置,j指示模式串中失配的位置,若 ,则下一趟匹配比较时,模式串的第( )位与主串中的第i位对齐。
查看答案与解析
答案: B
解析: KMP 算法发生失配时,主串指针 不回退,模式串指针由 调整为
因此下一趟比较时,模式串的第 位与主串中当前失配位置的第 位对齐,选择 B。
数组是根据模式串自身的前缀和后缀关系得到的,与主串下标 无关,所以 在这里没有意义;A、D 也不能利用已经匹配成功的前后缀信息。
- 【王道·卷七-Q04】 串'acaba'的next数组值为( )。
查看答案与解析
答案: C
解析: 采用题目所用的 1 起始下标约定,令 ,并根据当前位置之前子串的最长相等真前缀和真后缀确定其余值。
- ;
- ,这是约定的初始值;
- 求 时考查子串
ac,不存在非空的相等真前缀和真后缀,因此为 1; - 求 时考查子串
aca,最长相等真前缀和真后缀均为a,长度为 1,因此 ; - 求 时考查子串
acab,不存在非空的相等真前缀和真后缀,因此为 1。
所以 next 数组为
即 01121,选择 C。
4.2.3 KMP算法的进一步优化
- 【王道·卷八-Q04】 已知字符串 为"aabaabcabc",模式串 为"aaabc"。使用nextval优化后的KMP算法进行匹配,匹配到 且 时,失配 。则下次开始匹配时,i和 分别是( )。
查看答案与解析
答案: C
解析: 模式串 的前 3 个字符均为 a。当 时,主串字符为 b,模式串字符为 a,发生失配。若按普通 next 数组逐级回退,还会重复拿同一个主串字符 b 与前面的 a 比较;nextval 的作用正是跳过这种必然再次失配的比较。
对该位置有
失配后先令 ,随后按照 KMP 主循环的规则,在 时同时执行 和 ,于是下一次真正开始字符比较时
因此选择 C。
- 【竟成·模拟一-08】 已知模式串为"ababac",主串为"cbabababac"。在KMP算法匹配过程中,第一次出现"失配"时,i=j=0。则下列描述正确的是()。
查看答案与解析
答案: D
解析: 模式串 ababac 的普通 next 数组为 [-1,0,0,1,2,3],而优化后的 nextval 数组为
因此 B 把普通 next 数组误当成了 nextval 数组。
按 nextval 进行匹配并统计字符比较次数:
- 主串第 1 个字符
c与模式串第 1 个字符a比较,失配,累计 1 次;随后有效状态变为 。 - 主串第 2 个字符
b与模式串第 1 个字符a比较,失配,累计 2 次;随后变为 。 - 主串第 3~7 个字符
ababa与模式串前 5 个字符ababa依次匹配,共增加 5 次,累计 7 次。 - 主串第 8 个字符
b与模式串第 6 个字符c失配,累计 8 次。此时 ,而不是 ,所以 C 错误。 - 保持主串指针不变,主串第 8 个字符
b再与模式串第 4 个字符b比较,随后第 9 个字符a、第 10 个字符c继续匹配,共增加 3 次。
因而总比较次数为
D 正确。A 只描述了将 暂时置为 的中间状态;下一次真正进行字符比较前,算法还会令主串指针前移并将 恢复为 0,因此不能说主串指针始终不变。
- 【竟成·模拟六-03】 已知字符串S为"abaacaadaafa",模式串P为"aada"。采用KMP算法结合nextval数组进行匹配,匹配成功时共进行()次比较。
查看答案与解析
答案: B
解析: 模式串为 aada。采用从 1 开始编号的 KMP 约定,其 nextval 数组为
按题目所采用的算法判定口径,匹配过程如下:
- 主串第 1 个字符
a与模式串第 1 个字符a匹配。 - 主串第 2 个字符
b与模式串第 2 个字符a失配,模式串指针回退到 0;随后主串指针前移。 - 从主串第 3 个字符开始,
a、a分别与模式串前两个a匹配。 - 主串第 5 个字符
c与模式串第 3 个字符d失配,模式串指针退到第 2 个字符;c再与a失配,模式串指针再次退到 0,随后主串指针前移。 - 从主串第 6 个字符开始,子串
aada与模式串完整匹配。
整个过程中,按 KMP 主循环中的比较判定次数统计,共进行 12 次比较,因此选择 B。nextval 的作用是跳过模式串中必然会再次失配的位置,避免无意义的重复回退。