当前课程知识点:数据结构(下) > 第十一章 串(上) > (b2)蛮力匹配 > 11b2-4: 性能
以下 我们就分别从最好和最坏情况两个角度
对蛮力算法的计算效率作一评估
首先 最好情况显而易见
也就是我们在第一个对齐位置只经过一轮比对之后
就能确定整体匹配
在这种情况下 我们累计只需进行m次比对
因此整体消耗的时间 可以度量为O(m)
与文本串的长度n无关
相对而言 最坏情况要复杂很多
可以想象 在最坏情况下 我们可能需要尝试所有的对齐位置
而且 在每一个对齐位置 情况都糟糕透顶
具体来说 我们都需要经过m-1次成功的比对
并失败于最后一次比对
从而在每一个对齐位置 我们都需要付出 m次比对的成本
因此 累计的成本 应该是这两项的乘积
考虑到 在通常的情况下n要远远大于m
所以借助大O记号 可以更为简明地度量为O(nm)
如果考虑到无论n或者m都要远远大于常数
那么 这样一个复杂度 的确是不能令我们满意的
当然 至此你可能会怀疑 以上所设想的最坏情况 的确会发生吗
坏消息是很不幸 的确可能发生
比如 这就是一种最坏情况
此时的文本串和模式串类似
二者都是除了末字符为1 其余的字符都为0
不难发现 在任何一个对齐位置的故事 都是一样的
每次对齐之后
我们都会经过连续的m-1次成功的比对
并最终失败于最后一次比对
当然 这类最坏情况的出现概率 受到很多因素的影响
在通常的情况下 其中最主要的一个因素 莫过于字母表自身的大小
我们注意到 此类蛮力算法的效率之所以很低
其原因可以理解为它不足以处理这类大量的局部匹配
而字母表越小 可出现字母的种类也就越少
相应地 局部匹配的概率也就更高
因此 也相对更有可能导致最坏的情况
另一方面 最坏情况下的效率之所以极低
也可以理解为蛮力算法没有能够有效地避免这类局部的匹配
从而每次都是直到最终
才会发觉此前所获得的一系列局部匹配都是徒劳的
在这种极端的情况下 局部匹配的次数 取决于模式串的长度m
因此m越大 最坏情况所带来的后果也更为严重
然而反过来 一个好消息是
蛮力算法也并非如它的名字所暗示的那样百无一用
实际上 正如我们在习题解析中所补充证明的
随着字母表规模的扩大
以上最坏情况出现的概率将急剧下降
以至平均而言 在每一对齐位置
我们都大致只需常数次比对
这就意味着 就期望的意义而言
蛮力算法的时间复杂度可以接近甚至达到线性
当然 我们并不满足于此
而是期望能够将这个前提条件抹掉
从而得到一个堂堂正正的
即便在最坏情况下也只需运行线性时间的算法
而更好的消息是 这类算法的确存在
比如 我们接下来就要介绍的著名的KMP算法
-选课之前
--写在选课之前
--宣传片
-考核方式
--考核方式
-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)希尔排序:逆序对
-本章测验
--本章测试