当前课程知识点:数据结构(下) > 第十一章 串(上) > (c4)KMP算法:构造next[]表 > 11c4-2: 算法
在这里 我们需要牢牢抓住的要领
依然是next表项的那个必要条件 也就是前缀的自相似性
刚才 为了估算出next表的第j+1项
我们曾经尝试过在第j项的基础上去加1
因为根据刚才所建立的充要条件
只要P[j]与它的继任者是相等的
那么的确可以简明地通过加1得到下一项
那么即便P[j]与它的继任者不相等
这个必要条件依然可以适用
也就是说 在这种情况下为了估算出next表的第j+1项
下一个值得尝试的位置 依然需要满足自相似的必要条件
那么 对应的这个前缀的长度
也自然就应该是在此前长度的基础上 再去取一次对应的next表项
也就是说 从前缀长度的变化趋势来看
如果此前是将j替换为next[j]
那么接下来 就应该将next[j]替换为next[next[j]]
当然 如果仍有必要
我们还应该将next[next[j]]替换为next[next[next[j]]]
这个过程有可能会持续多步
一旦遇到这样一个相等的替代者
就可以在它所对应的这个前缀长度的基础上再累进一个单位
即可得到next表的下一项
概括而言 在估算next表下一项的过程中
我们应该按照这样一个序列依次尝试
请注意 因为next表项对应的都是真前缀与真后缀的长度
所以 对于任何一个j而言
其对应的next表项都会严格地小于它自己
这就意味着上述这个序列必然是严格递减的
整个儿算法迟早会收敛并终止
当然 最终的结局有可能是非常极端的
也就是说 有可能会一直尝试到0号位置
在这个图中 也就相当于模式串经过多次的位移 最终居然越过了i+1本身
按照通常的理解 此时会出现问题
因为接下来与P[j]进行比对的那个字符根本就无从谈起
而事实上这正是我们的哨兵能够大显身手的又一个场合
你应该记得这个假想的哨兵是一个通配的字符
所以作为假想的继任者
它必然在逻辑上也可等效为与P[j]相等
因此 即使整个计算过程到了这步田地
也必然会因为这次逻辑上的判等通过而随即终止
而且此时next表中对应的下一项
就应该是在-1的基础上再加1 也就是取作0
作为巩固练习
请你在课后自行验证一下
在这种情况下将next表的下一项视作0 的确是合理的
至此 只要纵观整个儿计算的过程
我们就不难发现这实质上就是模式串自己与自己不断匹配的过程
因此 只需基于KMP主算法的框架 略作修改
也自然就可以导出next表的递推计算算法
二者的区别实际上无外乎一点
也就是 新的这个算法需要实时地输出next表的下一项
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-OJ系统说明
--关于OJ
--1-注册与登录
--2-界面与选课
--3-提交测试
-关于课程教材与讲义
--课程教材与讲义
-关于讨论区
--关于讨论区
-微信平台
--html
-PA晋级申请
--PA晋级
-(a)概述
--07A-1 纵览
--07A-5 接口
-(a)概述--作业
-(b1)BST:查找
-第七章 二叉搜索树--(b1)BST:查找
-(b2)BST:插入
-(b2)BST:插入--作业
-(b3)BST:删除
-第七章 二叉搜索树--(b3)BST:删除
-(c)平衡与等价
-(c)平衡与等价--作业
-(d1)AVL树:重平衡
-第七章 二叉搜索树--(d1)AVL树:重平衡
-(d2)AVL树:插入
-(d2)AVL树:插入--作业
-(d3)AVL树:删除
-(d3)AVL树:删除--作业
-(d4)AVL树:(3+4)-重构
-(d4)AVL树:(3+4)-重构--作业
-本章测验
--章节测验
-(a1)伸展树:逐层伸展
--习题
-(a2)伸展树:双层伸展
--习题
-(a3)伸展树:算法实现
--习题
-(b1)B-树:动机
--习题
-(b2)B-树:结构
--习题
-(b3)B-树:查找
--习题
-(b4)B-树: 插入
--习题
-(b5)B-树: 删除
--习题
-(xa1)红黑树:动机
--习题
-(xa2)红黑树:结构
--习题
-(xa3)红黑树:插入
--习题
-(xa4)红黑树:删除
-本章测验
--习题
-(b)散列:原理
--09B-3 数组
--09B-4 原理
--09B-5 散列
--09B-6 冲突
--习题
-(c)散列:散列函数
--习题
-(d1)散列:排解冲突(1)
--习题
-(d2)散列:排解冲突(2)
--习题
-(e)桶/计数排序
--习题
-本章测验
--本章测试
-(a1)需求与动机
--习题
-(a2)基本实现
--习题
-(b1)完全二叉堆:结构
--习题
-(b2)完全二叉堆:插入与上滤
--习题
-(b3)完全二叉堆:删除与下滤
--习题
-(b4)完全二叉堆:批量建堆
--习题
-(c)堆排序
--习题
-(xa1)左式堆:结构
--习题
-(xa2)左式堆:合并
--习题
-(xa3)左式堆:插入与删除
-本章测验
--本章测试
-(a)ADT
--习题
-(b1)串匹配
--习题
-(b2)蛮力匹配
--习题
-(c1)KMP算法:从记忆力到预知力
--习题
-(c2)KMP算法:查询表
--习题
-(c3)KMP算法:理解next[]表
--习题
-(c4)KMP算法:构造next[]表
--习题
-(c5)KMP算法:分摊分析
--习题
-(c6)KMP算法:再改进
-(d1)BM_BC算法:以终为始
-(d2)BM_BC算法:坏字符
-(d3)BM_BC算法:构造bc[]
-(d4)BM_BC算法:性能分析
-(e1)BM_GS算法:好后缀
-(e2)BM_GS算法:构造gs表
-(e3)BM_GS算法:综合性能
-(f1)Karp-Rabin算法:串即是数
-(f2)Karp-Rabin算法:散列
-本章测验
--本章测试
-(a1)快速排序:算法A
-- 12a1-5: 实例
--习题
-(a2)快速排序:性能分析
--习题
-(a4)快速排序:变种
-(b1)选取:众数
-(b3)选取:通用算法
--习题
-(c1) 希尔排序:Shell序列
--习题
-(c2)希尔排序:逆序对
-本章测验
--本章测试