数据结构(邓俊辉)学习笔记】串 05——KMP算法:理解next[]表

news2024/11/14 22:05:27

文章目录

  • 1.快速移动
  • 2.避免回溯
  • 3.通配哨兵

1.快速移动

在接下来这节,就让我们从严格的意义上来理解 next 表的具体含义及其原理。
在这里插入图片描述

我们已经切实地看到, KMP 算法的优化效果首先体现在它可以使模式串得以快速地后移,而不是如蛮力算法那样只能亦步亦趋。反过来我们也可以认为 KMP 可以聪明地排除掉很多不必要的对齐位置。 而这些位置之所以被排除掉,是因为 KMP 发现它们不具备某种必要条件,正如我们马上就要看到的,这种必要条件就具体体现为模式串自身的某种匹配性。

依然回到这样一个串匹配的典型场景。我们在 T[i] 与 P[j] 之间发现了一次失配,接下来 KMP 会去查询 next 表,取出对应的表项 t,并用 P[t] 来取代此前的 P[j],使之继续以此前的 T[i] 相对齐,并从这个位置出发,继续后续的比对。

我们的问题是, KMP 在这种场合为何会选定这样一个特定的 t 呢?或者说,这样的 t 又具备哪些必要条件呢?答案就藏在上图中。

  1. 我们来考察 t 所对应的这个前缀( P[0,t) ),在KMP算法中,这个前缀将不再会重复地接受比对。我们已经看到,之所以能够这样,是因为 KMP 已经预先判定,这个前缀必然会与主串中对应的这个子串( P[ j - t, j) ) 完全匹配。在这里,我们需要回过头来考察,此前 P[j] 所对应的这个前缀,同样地,这个前缀在当年也应该和这个子串(i 所对应的行)是完全匹配的,因此,相对于它,文本串中这个长度为 t 的子串( P[ j - t, j) ) 就是一个后缀。
  2. 另一方面,既然这个新的前缀( P[0,t) ) 是由此前的前缀(j 所对应的行)经过右移之后而得到的,所以同样相对于此前的这个前缀,它依然是一个长度为 t 的前缀。

由此,我们也就得出了关于 t 的一个至关重要的必要条件:也就是说,在此前的这个前缀中,必须有一个长度为 t 的前缀与长度为 t 的后缀彼此相等。也就是说在相对于 P[j] 而言的这个前缀中,其首部和尾部必须具有一定的相似性。 这个必要条件,可以形式化地表示为上图中的等式。其左侧是一个真前缀,而右侧则是一个真后缀。

就任何一个特定的模式串 P 而言,对于区间内的任何一个整数 j,如果将满足上述条件的 t 筛选出来,就可以得到这样一个候选集合。

根据刚才的分析,既然这些 t 都满足上述必要条件,那么一旦在 T[i] 和 P[j] 处发生一次失配,只有来自于这个集合中的 t, 才有资格作为下一轮的对齐位置。

2.避免回溯

当然,你应该记得在这种情况下,KMP 并不会去逐一尝试所有的 t。事实上,在 next 表中,针对于每一项只会给出唯一的一种选择。那么 KMP 所选取的,究竟是其中的哪一个呢?

为此,我们需要考察这里的位移量( j - t)。是的,如果是用 t 来取代原来的 j,那么对应的位移量就应该是 j 和 t 之差。在这里 j 是相对固定的,因此 t 越小,对应的位移就越大。反之,t 越大,相应的位移也就越小。而位移量更小,也就意味着某种意义上的更加安全。什么意义呢?避免回溯。

是的,KMP 在所有候选者中最终所选取的的确就是这个集合中最大的那个 t。如此可以保证对应的位移量是安全的。实际上,这种原则也暗藏了另一个不变性,也就是说,由 KMP 所舍弃的那些对齐位置,的确都是不值得对齐的。

3.通配哨兵

至此,严谨的你或许会有一个疑问,这里的候选者集合 N(P, j) 一定是非空的吗?因为对于空集而言,无论是选取最大元,还是选取任何一个元素,都是无从谈起的。然而实际上,这种担心是不必要的。在这里,我们注意到只要 j 是正数,那么这个集合就必然包含0。

然而遗憾的是,j 可能恰好就是 0。当然,此时 P[ j ] 所对应的前缀 P[0 ,j) 也自然是空串。而我们知道对于空串而言,所谓的真前缀和真后缀都是不可能存在的,也就是说,此时的候选集合的确是一个空集。
在这里插入图片描述

为了修补这一漏洞,KMP算法所给出的建议是,统一将 next 表中的第0项视为-1。那么如何来理解这个-1呢?
在这里插入图片描述

一种形象而有效的理解方式就是,为每一个模式串在首字符的前端,也就是等效于秩为 -1 的位置增设一个哨兵。当然,与所有假想的哨兵一样,这个哨兵并不需要真实的存在,但是在逻辑上,这个哨兵却等效于一个与所有字符都通配的字符。

你应该还记得,我们在介绍 KMP 主算法时所搁置起来的一个问题。也就是其中那个 if 语句所对应的条件式,你应该记得,除了常规的字符比对逻辑,KMP 还增设了另一个并列的逻辑,也就是 j 是否小于0。现在你应该恍然大悟了吧?

是的,在正常的情况下,所谓的 j < 0 无非就是一种情况。也就说,在刚刚过去的那一轮比对中,我们失败于首次符 P[0]。于是,按照我们刚才所建议的那种理解方式,KMP 将用这个假想的通配符,去与文本串中适配的那个 T[i] 继续比对。既然是通配符,所以接下来的第一次比对必然会成功。也正因为此,我们可以将 j < 0 的条件,在语义上与字符的成功比对等效起来。也就是说,这个合成的逻辑判断式,在语义上完全等效于一次成功的比对。

由此可见,巧妙地引入和设置哨兵,在程序和算法设计过程中是一种非常高明的处理手法,KMP 就是这方面的一个典型范例。概括而言,这种手法的高明之处主要体现在两个方面。

  1. 首先,在代码实现上可以使得算法的描述更为简洁。
  2. 其次,通过相应的建立一种假想的模型,反过来,也可以使得我们对算法的理解更为统一和深入。

我们知道,包括伽利略在内的许多著名物理学家,都擅长于在头脑中进行所谓的虚拟实验。而实际上,计算机科学中的这种假想模式与物理学中的虚拟实验有着异曲同工之妙。

至此,我们已经对 KMP 所使用的那个 next 查询表有了足够深刻的认识。那么接下来一个问题自然就是,从计算的角度来看,这样一份查询表又当如何构造出来呢?为此,我们又需要花费多少成本呢?

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

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

相关文章

jmeter连接mysql数据库以及常规用法

1、在jmeter中新建一个测试计划&#xff0c;在测试计划界面中点击浏览&#xff0c;选择连接mysql数据库的jar包 如果没有jar包可以去网上下载&#xff0c;也可以通过如下链接进行下载 链接: https://pan.baidu.com/s/1BI6f19KSzXGlkSOwbnequw 提取码: gn8e 2、然后创建线程组&a…

CentOS7安装docker小记

首先你得需要有一个虚拟机&#xff0c;我的配置如图&#xff1a; 安装docker的工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 指定阿里云的仓库 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.re…

生信机器学习入门3 - Scikit-Learn训练机器学习分类感知器

1. 在线读取iris数据集 import os import pandas as pd# 下载 try:s https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.dataprint(From URL:, s)df pd.read_csv(s,headerNone,encodingutf-8)except HTTPError:s iris.data# 读取.data文件&#xff0c;…

使用python导出Excel表格中的lua配置

背景&#xff1a;游戏开发中&#xff0c; 策划使用Excel配置游戏中的参数数据&#xff0c;写一个工具用于导出这些配置 工具选择使用 python来开发&#xff0c;这样Windows、macOS、Linux平台都可以使用&#xff0c;而且有丰富的第三方模块。 本机先安装python&#xff0c;我…

nvidia-cuda-tensorrt-cudnn下载网站

tensorrt:https://developer.nvidia.com/tensorrt/download cudnn:https://developer.nvidia.com/rdp/cudnn-archive cuda:https://developer.nvidia.com/cuda-toolkit-archive

Python编码系列—Python微服务架构:构建可扩展的云原生应用

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

积极讨论取真经 自力更生辟新径 攻克难题会有时

你是如何克服编程学习中的挫折感的&#xff1f; 编程学习之路上&#xff0c;挫折感就像一道道难以逾越的高墙&#xff0c;让许多人望而却步。然而&#xff0c;真正的编程高手都曾在这条路上跌倒过、迷茫过&#xff0c;却最终找到了突破的方法。你是如何在Bug的迷宫中找到出口的…

火绒补充

目录 为什补充&#xff1f; 用户界面优化&#xff1a; 性能提升&#xff1a; 启发式检测和行为分析&#xff1a; 恶意网址拦截&#xff1a; 系统修复功能&#xff1a; 网络安全防护&#xff1a; 云查杀引擎&#xff1a; 漏洞修复和补丁管理&#xff1a; 隐私保护&…

C++类和对象(5)——运算符重载(以日期类为例)

运算符重载的作用 假设我们此时实现了日期类的运算符重载&#xff0c;我们就可以 实现如图的很多功能&#xff0c;完成日期计算器的底层代码。 运算符重载关键字 运算符重载的关键字是operator。 比如你想重载‘’运算符&#xff0c;那么语法格式就是 返回类型 operator …

Linux驱动开发基础(sr04超声波模块)

所学来自百问网 目录 1. SR04 超声波简介 2. 硬件设计 3. 软件设计 4. 示例代码 4.1 驱动代码 4.1.1 轮询模式 4.1.2 中断模式 4.3 应用程序 4.4 Makefile 4.5 实验效果 1. SR04 超声波简介 超声波测距模块是利用超声波来测距。模块先发送超声波&#xff0c;然后接…

大数据技术概述

4v特点 volume&#xff08;体量大&#xff09; velocity&#xff08;处理速度快&#xff09; variety&#xff08;数据类型多&#xff09; value&#xff08;价值密度低&#xff09; 核心设计理念 并行化 规模经济 虚拟化 分布式系统满足需求 系统架构 大数据处理流程 采集…

找论文的方法:如何找到本领域研究方向所需要的论文进行泛读和精读?

1、参考其他研究者给出的该领域的reading lists&#xff1a; 例如&#xff0c;在异配图神经网络领域&#xff1a; Awesome Resource on Graph Neural Networks With Heterophily&#xff1a;https://github.com/alexfanjn/Graph-Neural-Networks-With-Heterophily 在图对抗攻…

快速掌握GPTEngineer:用AI创建网页应用的实用教程

今天来聊聊一个非常有趣的工具——GPTEngineer。这是一个基于AI的网页开发平台&#xff0c;特别适合那些不熟悉编程但又想快速创建网页应用的人。如果你想用简单的文本描述来生成一个网站或者应用&#xff0c;GPTEngineer可能就是你需要的。我们一步步看看如何使用它。 1. 了解…

Guava Cache实现原理及最佳实践

本文内容包括Guava Cache的使用、核心机制的讲解、核心源代码的分析以及最佳实践的说明。 概要 Guava Cache是一款非常优秀本地缓存&#xff0c;使用起来非常灵活&#xff0c;功能也十分强大。Guava Cache说简单点就是一个支持LRU的ConcurrentHashMap&#xff0c;并提供了基于…

Java面试宝典-java基础08

Java面试宝典-java基础08 71、BIO、NIO、AIO有哪些应用场景72、简述一下BIO的编程流程73、NIO的三大核心部分是什么&#xff1f;74、NIO中buffer的四大属性是什么&#xff1f;75、对比一下BIO和NIO&#xff1f;76、FileChannel是做什么的&#xff1f;77、简述一下Selector选择器…

51单片机-矩阵键盘(基于LC602)

时间&#xff1a;2024.8.30 作者&#xff1a;Whappy 目的&#xff1a;手撕51&#xff08;第二遍&#xff09; 代码&#xff1a; main.c #include <REGX52.H> #include "LCD1602.h" #include "Delay.h" #include "MatrixKey.h"unsigned…

【Canvas与艺术】录王昌龄诗《从军行之四》

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>出塞青海长云暗雪山</title><style type"text/css&quo…

opencv实战项目十六:kmeans图像颜色聚类:

文章目录 前言K-means介绍效果 前言 在数字化时代&#xff0c;图像处理技术已成为计算机视觉领域的重要组成部分。其中&#xff0c;图像颜色聚类作为一项关键技术在众多应用场景中发挥着重要作用&#xff0c;如图像分割、物体识别、色彩调整等。K-means算法作为一种经典的聚类…

Java性能优化传奇之旅--Java万亿级性能优化之电商平台高峰时段性能大作战:策略与趋势洞察

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

Redis基础知识学习(入门篇)

文章目录 五大数据结构一. String: 字符串二. Hash: 散列概念性质 三. List: 列表四. Set: 集合特点 五. Sorted Set: 有序集合 五大数据结构 一. String: 字符串 数据结构中&#xff0c;字符串要单独用一种存储结构来存储&#xff0c;称为串存储结构。这里的串指的就是字符串…