数据结构(邓俊辉)学习笔记】串 07——KMP算法:分摊分析

news2024/9/20 22:50:56

文章目录

  • 1.失之粗糙
  • 2.精准估计

1.失之粗糙

以下,就来对 KMP 算法的性能做一分析。我们知道 KMP 算法的计算过程可以根据对齐位置相应的分为若干个阶段,然而每一个阶段所对应的计算量是有很大区别的。很快就会看到,如果只是简单地从最坏的角度来进行估计,我们将无法准确地来评估这种算法,而实际上真正有效的方法是,放眼整个计算过程,将整体的计算成本分摊到每一个阶段。

没错,分摊。我们这里需要再一次地借助分摊的分析技巧,而这里我们将要采用的估算方法也是分拆分析中的一种典型手法。

我们首先来看一种貌似无可厚非,但实则非常粗糙的估算方法。
在这里插入图片描述

这一方法建议我们将注意力放在文本串中的任意字符上,因为这种方法认为,我们只要估算出每一个字符所参与的比对次数,也自然地就可以得到整体的比对次数。然而我们很快就会发现,在任何一个特定的字符处,我们的模式串的确有可能会多次地后移。实际上不能构造出这样的例子,也就是相对于文本串中的某个特定字符,模式串有可能需要连续的后移多次,并且用其中多答 Ω(m) 个字符,与文本串中的这个字符进行比对。当然具体的次数可能是m/3、m/40 或者m/500。但无论如何,在渐进的意义上,都可以达到Ω(m)次。因此,如果再考虑到主串所贡献的那个因子 n,那么按照这种思路,KMP 的时间复杂度似乎会高达Ω(n*m)。

这样一个分析结论多少会让我们感到沮丧,因为蛮力算法也不过如此。然而事实上,这种方法的确实失之粗糙,而接下来更为精细地分析将表明,KMP 算法的效率即便在最坏情况下也不会超过线性O(n)。

2.精准估计

在这里插入图片描述为了对KMP算法性能作出更为精细的分析,我们可以参照在第一章就确立的方法,将这个算法中,不涉及到实质计算内容的非迭代部分都删除掉,而将注意力集中于复杂度的主体,也就是其中的这个循环。

在这里,我们需要引入一个观察量 k。 在算法执行过程中的任何时刻,这个 k 都等于 2*i - j。实际上,在很多开发环境中,都提供了观察功能,允许你设置这样一个表达式,并且在算法的调试运行过程中,动态地给出表达式所对应的数值。

实际上,随的算法中这个迭代过程的不断推进,这个观察变量 k, 必然是单调递增的。这一性质并不难看出,实际上无非 if 和 else 两种可能。

  1. 首先,如果当前这步迭代选取的是 if 分支,那么,根据算法的流程,i 和 j 会同步地递增一个单位。于是,作为 2*i - j,k 应该恰好增加一个单位。
  2. 反之,如果当前这步迭代进入的是 else 分支,那么尽管 i 不会受到任何影响,但是 j 会被替换为它对应的 next 表项,你应该记得我们此前已经指出, j 所对应的那个 next 表项必然会严格地小于 j。也就是说,经过这样一次替代之后,在数值上 j 必然会严格地减少,所以 k 也至少会增加一个单位。

综合这两种情况,我们就会发现 ,k 随着迭代的进行的确会严格单调地不断递增。

因此,整个计算过程中所进行的迭代步数就绝对不会超过 k。也就是说只要我们能够界定 k 的上界,也就自然确定了整个算法复杂度的上界。那么 k 的变化幅度究竟是多大呢?

  1. 首先,既然 i 和 j 的初值都是0,所以 k 的初值也应该是0。
  2. 而在算法结束时,i 至多与 n 同阶,而 j 也至少是一个常数。这也就意味着在渐进的意义上,k 绝对不会超过线性的范围。

至此,我们也就确凿地给出了 KMP 算法性能的一个准确估计。是的,这里给出的估计方法非常初等,因此其结论也毋庸置疑。

当然,作为进一步的探求,你或许会好奇于这里的 k,也就是 2*i - j 的具体含义,自行探索。

在这里插入图片描述

当然,作为 KMP 算法的有机组成部分,我们也不要忘了 next 表的构造过程。然而,正如我们已经看到的,这个预处理算法的原理及过程与主算法完全相同,因此其复杂度也应该线性正比于它自己的输入规模,也就是模式串的长度 O(m)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2079950.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

K8S的持久化存储

文章目录 一、持久化存储emptyDir实际操作 hostPath建立过程 NFS存储NFS 存储的优点NFS 存储的缺点具体操作 pv和pvcPersistent Volume (PV)使用场景 Persistent Volume Claim (PVC)使用场景 使用 PV 和 PVC 的场景实际操作 StorageClassStorageClass 概述应用场景实际应用 一、…

实用攻略:亲身试用,高效数据恢复软件推荐!

今天要跟大家分享一下我使用几款数据恢复软件的经历。如果你曾经丢失过重要的文件,那除了注意备份外,也可以尝试一下这些非常棒的免费数据恢复软件! 第一款:福昕数据恢复 链接:www.pdf365.cn/foxit-restore/ 首先聊…

Nginx+ModSecurity(3.0.x)安装教程及配置WAF规则文件

本文主要介绍ModSecurity v3.0.x在Nginx环境下的安装、WAF规则文件配置、以及防御效果的验证,因此对于Nginx仅进行简单化安装。 服务器操作系统:linux 位最小化安装 一、安装相关依赖工具 Bash yum install -y git wget epel-release yum install -y g…

大模型企业应用落地系列二》基于大模型的对话式推荐系统》核心技术架构设计图

注:此文章内容均节选自充电了么创始人,CEO兼CTO陈敬雷老师的新书《自然语言处理原理与实战》(人工智能科学与技术丛书)【陈敬雷编著】【清华大学出版社】 文章目录 大模型企业应用落地系列二基于大模型的对话式推荐系统》心技术架…

【精品】计算机毕业设计之:springboot游戏分享网站(源码+文档+辅导)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

win11,vscode上用docker环境跑项目

1.首先用dockerfile创建docker镜像 以下是dockerfile文件的内容: FROM pytorch/pytorch:1.11.0-cuda11.3-cudnn8-devel LABEL Service"SparseInstanceActivation"ENV TZEurope/Moscow ENV DETECTRON_TAGv0.6 ARG DEBIAN_FRONTENDnoninteractiveRUN apt-…

JavaScript:js;知识回顾;笔记分享

一,js前奏 1,js简介: Javascript是一种由Netscape(网景)的LiveScript发展而来的原型化继承的面向对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如Perl,遗留的速度问题&a…

数据结构与算法(1)

抽象数据类型定义 算法的效率 时间效率 一个算法的运行时间是指一个算法在计算机上运行所耗费的时间 大致可以等于计算机执行一种简单的操作(如赋值、比较、移动等) 所需的时间与算法中进行的简单操作次数乘积。 比较时间复杂度(看数量级) 空…

【STM32】RTC

忠实的时间记录者——RTC,板子断电也能继续记录(当然,得有纽扣电池供电)。 大部分图片来源:正点原子HAL库课程 专栏目录:记录自己的嵌入式学习之路-CSDN博客 目录 1 概述 2 应用 3 RTC方案 4 …

javacv-ffmpeg ProcessBuilder批量旋转图片

javacv-ffmpeg ProcessBuilder实现对图片的旋转,最近需要处理很多图片,量有点多,所以不能一个一个去编辑旋转图片,所以写一个工具类,实现对图片的旋转 maven配置文件,加上对ffmpeg的依赖,由于f…

关于自定义控件,头文件找不到问题的解决办法

在ui文件中使用控件提升的时候,突然发现ui_xxxx.h竟然报错了, 这在之前是没有碰到过,苦思过后认为是环境变量的问题,因为现在正在用的构建套件是 mingw 的,但在此之前我一直用的是msvc,并且环境变量的配置…

骑行耳机该怎么选?精选南卡、骨聆、小米多款顶尖实用品牌!

骨传导耳机,作为运动骑行领域的黑科技伴侣,以其独特的传音方式,让众多骑行运动爱好者在享受音乐的同时,依然能清晰感知外界环境,提升运动安全与乐趣。然而,随着骨传导耳机热度增加,市面上开始出…

Prometheus监控Kubernetes ETCD

文章目录 一、kubeadm方式部署etcd1.修改etcd指标接口监听地址2.prometheus中添加etcd的服务发现配置3.创建etcd的service4.grafana添加etcd监控模版 二、二进制方式部署k8s etcd1.将etcd服务代理到k8s集群2.创建etcd证书的secrets3.prometheus挂载etcd证书的secrets4.promethe…

63. 不同路径 II -dp7

63. 不同路径 IIhttps://leetcode.cn/problems/unique-paths-ii/ 输入:obstacleGrid [[0,0,0],[0,1,0],[0,0,0]] 输出:2 解释:3x3 网格的正中间有一个障碍物。 从左上角到右下角一共有 2 条不同的路径: 1. 向右 -> 向右 ->…

Chrome 中的 RCE 会在 JIT 编译器中产生不正确的副作用

此类漏洞通常是“一键式”攻击的起点,当受害者访问恶意网站时,该漏洞会危害受害者的设备。Chrome 中的渲染器 RCE 允许攻击者危害 Chrome 渲染器进程并执行任意代码。但是,渲染器进程的权限有限,因此攻击者需要将此类漏洞与第二个“沙盒逃逸”漏洞串联起来:Chrome 浏览器进…

C#WinFrom 中实现可自定义按钮和事件的消息提示框

实现效果: public partial class CustomMessageBox : Form {// 声明按钮和标签控件private Button btnOption1;private Button btnOption2;private Label lblMessage;// 自定义属性用于获取对话框的结果public DialogResult DialogResult1 { get; private set; }// …

一文弄懂SQL事务隔离级别

SQL 事务隔离级别 在多用户数据库系统中,为了保证数据的完整性和一致性,SQL 标准提出了四种事务隔离级别,以规避脏读、不可重复读和幻读等问题。以下是四种隔离级别的简要介绍: 读未提交(read uncommitted&#xff09…

产业报告 | 2024年中国低空经济产业研究报告

低空经济是指以各种有人驾驶和无人驾驶航空器的各类低空飞行活动为牵引,辐射带动航空器研发、生产、销售以及低空飞行活动相关的基础设施建设运营、飞行保障、衍生综合服务等领域产业融合发展的综合经济形态。 基于启信产业大脑的海量数据与专业研判模型&#xff0…

【Linux C++】log4cpp日志库的安装和使用详解

log4cpp 是一个开源的 C 日志库,灵感来源于 Java 的 log4j。它提供了灵活的日志记录功能,可以帮助开发者在 C 应用程序中记录、管理和格式化日志信息。log4cpp 支持多种日志记录策略和输出目标,可以满足各种不同的需求。 1.安装 下载压缩包…

2.2.2 Posix API与网络协议栈2

接上回2.2.2 posix api 2 传输数据 四线一⚪,kernel 协议栈 send- write, recv-read 如何知道send成功? 如果返回整数,只能证明data从user copy到内核kernel wmemory了 就是数据传输是异步的,send是从application cop…