当前课程知识点:数据结构(下) > 第十一章 串(上) > (c1)KMP算法:从记忆力到预知力 > 11c1-1: 重复匹配的前缀
关于串匹配
包括蛮力算法在内
据我所知 至少有30多种知名的算法
而接下来 我们就将介绍其中最为经典的KMP算法
这个算法之所以著名
不仅是由于它出自包括Knuth在内的若干名人之手
而更为重要的是 它正如我们此前所期盼的那样
能够保证即便在最坏的情况下 运行时间也不超过线性
当然 在这一部分的末尾 我们也将通过对比指出
这一算法从某种意义上讲 也是被过度地神话了
正所谓不破不立
我们的KMP之旅 是起始于蛮力算法
让我们首先来揭示 蛮力算法为什么会如此低效
从宏观上来看
蛮力算法的一次典型的运行过程 可以由这样一幅图来示意
假定这就是足够长的一个文本串
而下边则是相对而言更短的模式串
我们知道 在算法的每一步迭代中
相对于文本串
模式串都有一个相应的对齐位置
请注意 在这个算法中
相邻的对齐位置之间 间隔都是一个字符
在每一对齐位置
这个算法都需要从首字符开始
进行一系列的比对
直至在某个位置发生失配
请注意 在此之前每一次迭代所花费的时间 都正比于这样一个前缀
在这个图中 我们可以清晰地看到
所有这些前缀之间
存在着大量的重复
也就是说 在此前曾经参与比对的字符
在后续的迭代中
往往还会再次地参与比对
如果我们将视线集中于文本串中的某一特定字符
就会发现 在最坏情况下 它有可能会与模式串中的每一个字符都比较一次
也就是说 文本串中的每一个字符 都有可能参与多达m次的比对
依然回到我们上一节末尾针对蛮力算法所给的那个最坏实例
我们可以从这样一个新的角度来阐释 为什么蛮力算法效率如此低下
因为站在文本串中每一个字符的角度来看
在这种最坏情况下
它都会与模式串中的每一个字符比对一次
在这类最坏情况下
每一步迭代 都需要经过长途跋涉
才能够在最后一个位置发现失配
因此反过来 这类情况之所以棘手
也可以理解为在模式串中存在大量与文本串能够局部匹配的前缀
而蛮力算法的计算成本 也主要消耗于这些前缀中
然而 在对这个具体的实例进一步观察之后
我们或许会发现
这些局部匹配前缀所涉及的比对
绝大多数都是不必进行的
至少不必反复进行
你能看出其中的原因吗
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-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)希尔排序:逆序对
-本章测验
--本章测试