当前课程知识点:数据结构(下) > 第十一章 串(下) > (e2)BM_GS算法:构造gs表 > 11e2: 构造gs表
以下 我们就来简要地介绍gs表的具体构造算法
为了便于理解其原理
这里将整个算法划分为若干个层次
并逐层递进 逐层细化
我们首先需要引入MS子串与ss表的概念
实际上 相对于模式串中的任何一个字符P[j]
所谓的MS[j]
就是某个以P[j]为末字符的子串
而且 这个子串也同样会出现于整个模式串的尾部
当然 如果同时存在多个这样的候选
我们会在其中选择最长的那个
概括而言 所谓的MS[j]
就是终止于P[j]
同时与全串的后缀实现最长匹配的子串
当然 这个子串也有可能是空
我们来看这样一个实例
对于P[8] 也就是字符E而言
它所对应的MS子串自右向左由E、C、I、R这4个字符组成
因为这个子串与整个模式串的后缀
实现了最长的匹配
相应地 在ss表中
j所对应的那一项
其实也就是MS[j]子串的长度
在刚才这个例子中
8号字符E所对应的ss表项 也自然就应该是子串RICE的长度4
同理 对于字符P[2]而言
它所对应的MS子串为ICE
相应的ss表项 也就是这个串的长度 3
实际上 在中转的这个ss表中
已经蕴含了我们最终要计算的gs表的所有信息
因此 快速构造gs表的问题
也就自然地转化为了如何快速地构造ss表
那么 通过ss表 具体地如何构造出最终的gs表呢
无非两种情况
首先 ss[j]可能达到最大的极限 也就是j+1
此时的情况如这个图所示
也就是说 MS[j]子串足够长
以至于它就是整个模式串的一个前缀
于是 对于这个范围内的任何一个字符P[i]
一旦在扫描比对中发生失配
m-j-1也必然是一个值得考虑的位移距离
此外 都是一般的情况
也就是MS[j]子串的长度充其量不过j
此时的情况可以由下面这幅图来示意
可以看到 此时的MS[j]子串
长度还没有达到极限
于是如果将来在扫描比对的过程中在这个位置处发生首次失配
接下来一种值得考虑的位移距离自然也是m-j-1
通过以上的分析可以看到
构造gs表 关键就在于如何构造出ss表
当然 根据以上定义
即便采用蛮力策略
也是可以构造出这个表的
然而很遗憾
我们为此需要平方量级的时间
那么 这个结果能否改进呢
答案是肯定的
在我们的习题解析中
给出了具体的算法描述
以及代码实现
好消息是 采用这一新的算法
我们只需线性的时间
就足以构造出gs表
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-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)希尔排序:逆序对
-本章测验
--本章测试