数据结构(邓俊辉)学习笔记】串 04——KMP算法:查询表

news2024/9/20 22:32:30

文章目录

  • 1.制表备查
  • 2.主算法
  • 3.实例

1.制表备查

在这里插入图片描述

接下来我们来看看。KMP 算法究竟如何兑现我们刚才所提及的记忆力以及预知力,我们将会看到这种方法非常的便捷与高效,本质上讲,它无非就是构造了一张查询表。

回到我们刚才的问题,在当前这一轮比对,首次失败于 T[i] 与 P[j] 之后,我们应当如何地向后滑动模式串,从而等效地以一个新的 P[j] 来与刚才的 T[i] 对齐,并从这个位置开始继续新一轮的比对。

这里的好消息是,新的这个 P[j] 不仅可以事先确定,而且这个位置仅取决于模式串,而于主串无关。你能看出,为什么与主串没有关系吗?是的,事实上,在这样的一个时刻,主串无非4个部分,也就是文本串的这个前缀以及后缀,再加上在当前这一轮已经匹配的这个子串,以及失配的这个字符。不难看出,这个前缀与后缀对于新的这个 P[j] 字符的确没有任何影响。而这个子串表面上看对它有所影响,但正因为这个子串与模式串的前缀是匹配的,所以与其说这种影响是来自于文本串,不如说最终还是来自于模式串。能否看透这一点,对于我们以下理解KMP 算法至关重要。

既然下一个接替的字符完全取决于模式串自身,由此出发,再进一步地,与其说这个接替的字符是取决于模式串,不如说它取决于被它顶替的此前的那个 P[j]。事实上在一个长度为 m 的模式串中,这样的字符 P[j] 无非 m 种情况。

而 KMP 算法在此处的关键诀窍在于,将所有这 m 种情况事先处理,并且归纳整理为一张查询表。在经过了这样的预处理之后,在后续的各轮比对中,一旦在某一位置 P[j] 处发生失配,我们只需简单地从查询表中取出对应的那一项,并用它来更新此前的 j。

由此可见,这种策略与其说是在借助强大的记忆力,不如说是在事先已经为各种情况准备好了充分的预案。那么基于这种以查询表的形式给出的预案,KMP 算法又是如何具体工作的呢?

2.主算法

在这里插入图片描述

现在就来考察 KMP 的主算法,可以看到,无论接口形式还是算法的主体流程,KMP 与我们此前蛮力算法的版本一都颇为类似。是的,它的确是在版本一的基础上略加修改而得。

尽管在形式上这种改动非常的细微,但是在本质上却有巨大的区别。

  1. 首先,这里增加了一步预处理,也就是构造出我们刚才所说的那份查询表,我们称之为 next 表。正如我们刚才所言,这个构造过程仅仅取决于模式串,而与文本串没有任何关系,因此是名副其实的预处理;
  2. 接下来与蛮力算法一样,我们也需要两个整数 i 和 j ,分别指向文本串和模式串中当前接受比对的那一对字符。
  3. 算法的主体循环也基本类似, if 分支完全一样。差异仅仅体现在 else 分支,可以看到 KMP 算法在失配情况下的处理更为简明。具体来说,只需从查询表中取出 j 所对应的那一项,并且用它来替换此前的 j。请注意,在这种情况下,KMP 并没有修改变量 i,也就是说它依然指向文本串中此前刚刚失配的那个字符。

这样的处理过程可以由上面插图来说明。请再次确认,此时情况也就是在当前的这轮比对中,主串的字符 T[i] 与模式串的字符 P[j] 首次发生了失配,在算法中也就对应于那个 else 分支,在这种情况下,如果此前模式串所对应的那个前缀长度为 j,那么接下来 KMP 算法将会把这个前缀替换为长度为 next [j] 的那个新的前缀,并从刚才适配的那个位置出发,继续下一轮比对。

当然,细心的你可能会发现,相对于蛮力算法,这里的 if 分支也并非完全地一样。是的,在对应的逻辑判断式中,这里新增了一个并列的条件,j < 0。关于这个条件的妙用之处,现在来谈,还为时过早,我们不妨暂且将其搁置起来。

3.实例

在这里插入图片描述

由上可见,KMP算法的核心就在于那张查询表 next。 在分析这张表的具体原理及其构造过程之前,我们不妨先通过一个实例来切实领会这张表的精妙之处。

考察这个由10个字符所构成的模式串,这里我们直接给出其对应的查询表,请关注其中倒数第三个字符 l,它所对应的秩为 j 等于7,而在查询表中,它所对应的 next 值为3。下面我们就来看看这个表项3所对应的含义及其功能。

假定,这就是主串(chinchi*),如果的确轮到这个表项在发挥作用,那么就意味着在当前这一轮比对中,此前的7个字符都应该是成功的。就是说此时的场景必然是这样(主串上面的模式串),具体来说也就是,模式串中的这个字符 l 与文本串中某个不是 l 的字符比对失败。此时针对这种情况,KMP 算法将会如何处置呢?

为便于对比效果,在处置之前,我不妨先为模式串拍摄一张快照,就像这样(chinchilla)。

现在我们手动来执行一下 KMP 算法

  1. 首先,当前的 j 为7指向模式串中的这个字符 l;

  2. 接下来, KMP 将在查询表中取出对应的那一项,并用它来更新 j。我们刚才已经看到这个表象,就是3,这就意味着接下来 KMP 将会用秩为3的那个字符,也就是 n, 来取代刚才的 l,并继续与文本串中此前失配的那个字符级对齐,就像这样。

    此时我们不妨为模式串再拍摄一张快照。

对比前后两张快照,我们会发现,其效果等同于模式串向后移动了4个字符。不难看出,这个4是来自于7和3的差。从另一角度来看,这些等效于 KMP 聪明地排除掉了3个不必要的对齐位置。是的,这 3 个位置都是无需对齐的,因为它们都不具备足以对齐的必要条件。比如它们所对应的首字符都不是模式上的首字符 c。而反过来,KMP通过 next 表选择了字符 n,从某种意义上讲是非常合理的。没错,它使得相对于 n 而言的这个前缀,依然与主串是匹配的。 具体来说,c 依然对应于 c,h 依然对应于 h,而 i 也依然对应于 i。

是的,通过这样一个实例,我们的确已经能够感受到 KMP 算法及其中 next 表的精妙之处,但严格上来说,在这种精妙的背后究竟是什么样的原理呢?

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

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

相关文章

Windows中pycharm使用虚拟环境不显示虚拟环境的名也不出现base

出现下图情况 一、修改shell path 二、环境变量中加入condabin 三、如果上述还不行&#xff0c;初始化conda再进行一、二、操作 最终进入了我创建的虚拟环境b中

【html+css 绚丽Loading】000017 三元轮转镜

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

VCTP(Visual Chain-of-Thought Prompting for Knowledge-Based Visual Reasoning)论文

目录 摘要介绍相关工作方法总体模型细节 实验 摘要 知识型视觉推理仍然是一个艰巨的任务&#xff0c;因为它不仅要求机器从视觉场景中解释概念和关系&#xff0c;而且还需要将它们与外部世界知识联系起来&#xff0c;对开放世界问题进行推理链。然而&#xff0c;以前的工作将视…

论文文献翻译怎么做?快又准的外文文献翻译软件帮你搞定

平时我们查阅文献通常都是将其翻译成中文&#xff0c;方便更高效和准确地理解和阅读&#xff1b;但对于不少留学生而言&#xff0c;如何把文献翻译成英文也是他们需要解决的一大硬茬~ 今天就给大家盘点了4个能够把文献翻译成英文的实用小技巧&#xff0c;有需要的小伙伴可别错…

PicHoro v2.4.0 — 强大的图床管理,可导入PicGo配置

PicHoro是一款基于Flutter开发的手机端云存储平台&#xff0c;支持多种云存储服务和图床&#xff0c;提供便捷的文件管理和分享功能。兼容多种云存储和图床平台&#xff0c;包括Webdav、Alist、SSH/SFTP、S3 API、腾讯云COS、阿里云OSS、七牛云、又拍云、Imgur、SM.MS以及Githu…

Java基础入门20:特殊文件、日志技术、多线程、网络通信

特殊文件 properties属性文件 Properties是一个Mp集合&#xff08;键值对集合&#xff09;&#xff0c;但是我们一般不会当集合使用。 核心作用&#xff1a;Properties是用来代表属性文件的&#xff0c;通过Properties可以读写属性文件里的内容。 使用Properties把键值对数…

【STM32】电容触摸按键

电容按键就是酷&#xff0c;但据我使用过电容按键版的洗澡计费机子后&#xff0c;一生黑&#xff08;湿手优化没做好的电容按键简直稀碎&#xff09;。 大部分图片来源&#xff1a;正点原子HAL库课程 专栏目录&#xff1a;记录自己的嵌入式学习之路-CSDN博客 目录 1 触摸按…

IPv4和IPv6的区别是什么?什么是局域网和广域网,公网IP和私有IP?

文章目录 1.基本网络2.局域网3.广域网4.IPv4与NAT5.公网IP和私有IP6.IPv6 1.基本网络 我们都知道计算机的数据都是存在各自硬盘中的,与其他计算机之间没有人任务关系. 假设计算机A需要给计算机B发送数据,可以选择使用U盘这类移动存储数据来拷贝数据来实现数据交互,但是这样一…

惊艳开源界!20.6K+星标瞩目,打造高性能LLM(大型语言模型)应用的开发平台

项目简介 Dify 是一个开源的LLM&#xff08;大型语言模型&#xff09;应用开发平台&#xff0c;它通过直观的界面结合了AI工作流程、RAG&#xff08;检索-分析-生成&#xff09;管道、代理功能、模型管理、可观察性特性等&#xff0c;使用户能够快速从原型设计转向产品生产。 …

一起搭WPF之列表数据绑定

一起搭WPF之列表数据绑定 1 前言2 数据绑定2.1 前端2.2 后端实现2.2.1 界面后台2.2.2 模型与逻辑 3 问题3.2 解决 总结 1 前言 之前已经简单介绍了列表的大致设计&#xff0c;在设计完列表界面后&#xff0c;我们可以开展列表的数据绑定&#xff0c;在前端显示我们的数据&…

【问题处理】前端Vue项目遇到的一些问题及处理方式

每次新整一个项目的时候&#xff0c;开端总是会遇到各种奇奇怪怪的问题&#xff0c;一步一坎的感觉&#xff0c;但是没关系&#xff0c;遇到了就一步一步去解决&#xff0c;当把所有问题都处理后&#xff0c;成功运行起来&#xff0c;就会突然很有成就感&#xff0c;一切都是那…

大模型嵌入向量Embeddings

版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhlEmbeddings概述 嵌入(Embeddings)概述 基本概念 嵌入,或称为Embeddings,在机器学习领域中扮演着至关重要的角色。它是一种将离散数据元素,如文本中的单词或图像中的像素点,映射到连续的向量…

虹科方案 | 疫苗冷链温度监测解决方案

通过WHO PQS标准的支持和稳定性预算的应用&#xff0c;我们可以更好地保障疫苗在全球范围内的安全运输和储存&#xff0c;接下来让我们了解一下既能计算药品剩余稳定性预算&#xff0c;又符合WHO PQS预认证的疫苗冷链温度监测解决方案。 疫苗冷链温度监测解决方案 根据WHO和《…

dpdk解析报文协议-基于l2fwd

dpdk解析报文协议-基于l2fwd 0 前置条件 1、这里需要两台虚拟机&#xff0c;配置了相同的虚拟网络&#xff0c;可以通过tcpreplay在一台虚拟机回放报文&#xff0c;在另一台虚拟机通过tcpdump -i 网卡名 捕获到。 具体配置可参考https://www.jb51.net/server/2946942fw.htm 2…

IP SSL:最快捷的安全证书

在这个数字化时代&#xff0c;企业面临着前所未有的挑战——如何在保证业务高效运行的同时保护其核心资产免受网络威胁。随着网络安全事件频发&#xff0c;企业和个人对数据安全的关注度达到了前所未有的高度。在此背景下&#xff0c;IP SSL&#xff08;Internet Protocol Secu…

Python分布式任务处理库之dramatiq使用详解

概要 在现代 Web 应用和数据处理任务中,异步任务处理是一个至关重要的部分。Dramatiq 是一个用于分布式任务处理的 Python 库,旨在提供简单、可靠的任务队列解决方案。与其他任务队列库相比,Dramatiq 更加轻量级,且易于上手。它的设计目标是帮助开发者轻松地将耗时的任务放…

【开源分享】在线客服系统PHP源码 带搭建教程

系统的主要特色功能 自动回复和机器人知识库&#xff1a;通过后台设置机器人知识库&#xff0c;系统可以根据关键词自动回复用户&#xff0c;提高响应速度和服务效率。 内容过滤&#xff1a;支持设置违禁词&#xff0c;避免接收包含不良信息的用户消息&#xff0c;维护平台健…

海康VisionMaster使用学习笔记17-定位项目误差分析及精度提高

定位问题排查步骤 机构及成像排查 标定过程排查 标定数据质量排查 标定结果排查 示教过程排查 注意事项总结

Kompose工具:转换Compose项目为K8S项目

Docker与Kubernetes系列 转换Compose项目为K8S项目 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.cs…

光储电站联合配置!多种调度模式下的光储电站经济性最优储能容量配置分析程序代码!

前言 不同于光伏独立系统以平衡负荷电量为目标&#xff0c;光伏电站需要跟踪调度中心下达的计划出力曲线。光伏发电存在随机性和波动性的特点&#xff0c;大规模集中式光伏电站集群引起出力变化&#xff0c;并且其有功功率上调节能力较弱&#xff0c;将大量占用系统备用资源&a…