当前课程知识点:数据结构(下) > 第十一章 串(下) > (d2)BM_BC算法:坏字符 > 11d2-2: 特殊情况
当然 实际的情况要更为复杂一些
我们不妨来看看 还有哪些特殊情况需要考虑并且处置
首先需要考虑的一种情况就是 在模式串中有可能同时存在多个X
那么在这种情况下
我们究竟应该用哪个X
来替换那个坏字符Y呢
与KMP算法一样
当同时存在多个候选时
我们并不倾向于像数学上那样
逐一地去尝试它们
而应该在安全的前提下
选择其一 从而使得我们不必回溯
也就是说 如果有多个候选
那么 我们倾向于选择其中对应的位移量尽可能小的那个
按照刚才的分析
任何一个字符所对应的位移量
都与这个字符在模式串中的秩
成反比
因此 为了使得位移量尽可能地小
所对应字符的秩
就应该尽可能地大
换而言之 当有多个候选时 我们应该首先选用其中的最靠后者
或者等价地
在相对于这个字符X的那个后缀中
必须不包含任何X
那么与此相反的另一种极端情况就是
在模式串中 可能没有任何这样的X可供选择
回忆一下 在我们此前所举的那个实例中 的确就有这种情况
比如 其中文本串中的那个“道”字
在模式串中根本就没有出现过
你应该还记得我们当时的处置方法
没错 我们只需将模式串完整地移过这个对齐的位置
那么 在相应的算法描述以及代码实现的过程中
我们又应该如何统一地来处置这种情况呢
没错 哨兵
与KMP算法一样
我们可以为每一个模式串在最左侧增设一个假想的通配哨兵
于是 所谓的将整个模式串移过这个位置
也就等效于用这个通配的哨兵
与刚才失配的字符对齐
既然是个通配字符
那么此前失配的这个字符
在此后就可以被忽略掉
实际上 除了以上所介绍的两种
还有一种更为特殊的情况需要处理
你能看出来吗
是的 在这种情况下模式串中的确至少存在一个候选的字符X
然而 其中最靠右的那个 位置又过于靠右
也就是说 它所对应的那个bc表项
或者说它的秩
太大了
高过了j
以至于通过二者之差所计算出来的位移量
居然是一个负数
显然 这样的回溯是没有道理的
也是不必要的
因为作为这个算法的一条不变性
相对于任何时候的当前对齐位置
此前的所有对齐位置
都已经被淘汰掉了
因此根本没有必要再回过头去重新考虑
既然以前的所有对齐位置
都已被淘汰掉
而当前的这个对齐位置
也刚刚被否定掉了
所以 再直接而简洁不过的处置方法就是
将整个模式串向后移动一个字符
并进而考察下一个对齐位置
至此 我们已经兼顾到了可能发生的所有情况 包括特殊情况
我们知道 KMP算法的整个策略
完全是融入并体现于其中的next表
而这里的BM算法 也类似
其策略 也将最终融入并体现于bc表
以及稍后要介绍的gs表
那么 首先一个问题就是
bc表 又当如何构造出来呢
相应地 我们又需要花费多少时间呢
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-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)希尔排序:逆序对
-本章测验
--本章测试