KMP算法的及其原理

news2024/11/16 19:23:42

 KMP算法

首先 我们先了解一下 KMP算法的作用 str1 和str2 字符串 如果str1中包含str2 那么返回头位置

如果不包含返回-1

首先 我们先加入一个概念: 有一个next数组 next[i]的值为 str2 中 以i-1位置为结尾的字符串中 最长相同前缀后缀为多长(相同前缀后缀 不是对称  aba 中相等的后缀为a 而非ab ba(这个是对称) 且不要让前缀\后缀长度等于字符串  因为对于任何一个字符串来说 它本身的最长前缀/后缀都是它本身 肯定相等)

举个例子 a b a b f f位置的next值为2   0 1 位置的next值恒为-1

好 来开下流程 str2先匹配str1 两个指针齐头并进 到达第一个不满足的位置 它位置的next值为5 那么直接从str2的5位置接着匹配下去

 就是从这个X Y为不同的地方 然后str2 Z和str1 Y继续匹配  如果再不相同呢 就找到Z 的next答案 然后从答案位置匹配... 如果一直next到0了 都没匹配成功 那就让str1的指针++ 也就是说从Y+1为开头继续匹配

解释一下原因

 首先我们知道Z和Y匹配 本质上是看以N开头的字符串和整个str2匹配 但是为什么N到Y之间的那段不用看了呢 首先对于str2来说 因为X位置的答案为5 那么str2的前五个(0-4)和后五个一定相等对吧  然后因为我们str1和str2 X Y之前的部分已经判断完相等了对吧  所以str2的0-4 等于 (x-5)~(x-1) 然鸡皮N~Y-1 又和 (x-5)~(x-1)一一对应 所以0-4和N~Y-1 就一定相等

那为什么不能是本质上N+1和0位置上匹配呢 额 因为X Y位置不同了 所以他到这一定会断掉

哎 是不是感觉还有哪不对 是的 这只能解释 N到Y-1的部分不用判断 但是解释不了为什么N之前的不用判断  

好 我们假设N之前有匹配的字符串 

对吧 假设S位置就可以匹配上了 那str2的前八个字符肯定和这个S开始的八个字符相同 再因为Y前的字符和X前的字符一 一相等 所以 S到Y-1 一定和下面str2中X-8到X-1的字符一 一对应 那也可以推出对于str2来说0~7和X-8到X-1相同 那X位置的next值应该是8啊 怎么能是5呢 这就冲突了 对不对 

所以基于这两个原理 str2可以直接和N进行比较

然后看做一个递归过程 如果我Z和Y没匹配上 那是不是又是一个同样的问题 哎 再去找Z的答案 一直找 找到str2开头0位置了 还没找到 那就说明真配不上 这整个一块都不行 你就把Y往下走吧

快速求next数组

反正跳出的时候 cn一定是当前位置的值 那到下一个循环的时候 cn就一定是上一个位置的结果 那str[cn]对应的是什么呢 就是要判断的位置啊 
因为next的值是前缀后缀相同的长度  如果这个位置的值是2  好 那我们就要判断第三个元素相不相同 如果相同 那就是值就是2+1 其实本来应该是前缀长度+1的位置的 但是正好 数组是从0开始的 都省了

那如果这个位置不同呢?  那就说明衔接不上 那我们再往前推一段

假如说a b a s a b a t g  这个数组 它对应位置的值为(是相等 不是对称)

         -1 0 0 1 0 1 2 3 

我们求g g位置本质是求t结尾的前缀后缀相同最大长度 a结尾的最大相同长度为3 哎 如果我这个t正好和第四个位置相同 是不是就直接套上了 可惜不同 那没办法 但是呢 也不一定直接为0 还要看我们3位置的值 因为你不能接在这个后面的话 那更短的位置呢 

假如这种情况 abagababs 我们求s位置的值 也就是以前一个字符结尾的那个值 虽然部门不能接到aba后面让最大相等长度为4 但是我们可以去看更前面 它和ab还是组成了前缀 后缀相同的

画个图直观理解一下

 

Y位置的结果 就是以Y-1结尾的最长相等前缀后缀 假如说已经求出来了 这两个方块区间代表 前缀和后缀 我们求Y+1的结果 那就是以Y结尾的最长相等前缀后缀  这两块区间肯定相等的 如果Y和X相等 那是最好的 我们直接上一个位置的值+1 就出结果了 但是不同呢?难道直接归零去比对吗 不 还可以优化

假如说x位置有值 这个值 就代表着前缀a 前缀b是相等的  那么在x的另一侧就有对应的 c 和d 相等

因为根据Y知道 x的左右两个大区间肯定是相等的

所以可以推出a和c相等 b和d相等

有了这几个条件 我们就知道了 a和d相等  所以Y如果和a的下一个字符配上了 那它的结果就等于x结果加1

那一直干到最开始都没匹配上 那就说明 没有了呗

OK我们开始coding

 public static int KMP(String str,String match) {
		char [] str1 = str.toCharArray();
		char [] str2 = match.toCharArray();
		int x = 0;
		int y = 0;
		int [] next = getnext(str2);
		while(x<str1.length&&y<str2.length) {
			if(str1[x]==str2[y]) {
				x++;
				y++;
			}else if(next[y]==-1){
				x++
			}else {
				y = next[y];
			}
		}
		return y == str2.length ? x - y : -1;//y走到头了 说明匹配出来了(y要比实际位置+1 走出while循环都这样) x走到头了说明没有
	}
    public static int [] getnext(char [] str) {
		int [] next = new int [str.length];
		next[0] = -1;
		next[1] = 0;
		int index = 2;
		int cn = 0;
		while(index<str.length) {
			if(str[index-1]==str[cn]) {
				next[index++] = ++cn;
			}else if(cn>0) {
				cn = next[cn];
			}else {
				next[index++] = 0;
			}
		}
		return next;
	}

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

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

相关文章

数字化转型与百数低代码平台:创新商业模式的商机突破口

随着科技的不断进步和全球经济的快速发展&#xff0c;企业数字化转型已经成为当今商业领域的热门话题。 根据Gartner的《2023年度董事会调查》显示&#xff0c;数字化转型已然是当今企业商业战略的一大基石&#xff0c;中国有36%的企业将数字化转型作为企业最优先的业务。 这表…

windows环境下,安装elasticsearch

jdk ElasticSearch是基于lucence开发的&#xff0c;也就是运行需要java jdk支持。 我下载了 elasticsearch-8.9.0-windows-x86_64.zip&#xff0c;带了OpenJDK。 ElasticSearch下载 https://www.elastic.co/downloads/elasticsearch 安装ElasticSearch 下载安装包后解压 修…

WMS仓储管理系统的建设理念包括哪些内容

WMS仓储管理系统是物流供应链管理领域中的重要组成部分&#xff0c;主要用于仓储过程的计划、控制和管理。WMS仓储管理系统解决方案可以有效协调人、设备和仓库资源&#xff0c;提高仓储效率、降低成本、确保准确性&#xff0c;为企业的物流运输及整个生产活动提供有力保障。那…

综合案例(面向对象)

使用面向对象思想完成数据读取和处理基于面向对象思想重新认知第三方库使用&#xff08;PyEcharts&#xff09; 数据分析案例 某公司&#xff0c;有2份数据文件&#xff0c;现需要对其进行分析处理&#xff0c;计算每日的销售额并以柱状图表的形式进行展示。 数据内容 综合案…

【Terraform学习】Terraform-docker部署快速入门(快速入门)

Terraform-docker部署快速入门 实验步骤 创建 EC2 IAM 角色 导航到IAM 在左侧菜单中&#xff0c;单击角色 。单击创建角色该按钮以创建新的 IAM 角色。 在创建角色部分&#xff0c;为角色选择可信实体类型&#xff1a; AWS 服务 使用案例:EC2 单击下一步 添加权限&#x…

LeetCode面向运气之Javascript—第2600题-K件物品的最大和-94.68%

LeetCode第2600题-K件物品的最大和 题目要求 袋子中装有一些物品&#xff0c;每个物品上都标记着数字 1 、0 或 -1 。 四个非负整数 numOnes 、numZeros 、numNegOnes 和 k 。 袋子最初包含&#xff1a; numOnes 件标记为 1 的物品。numZeroes 件标记为 0 的物品。numNegOn…

【GitOps系列】使用 ArgoCD 快速打造GitOps工作流

文章目录 ArgoCD简介ArgoCD安装访问ArgoCDGitOps 工作流总览创建 ArgoCD 应用检查 ArgoCD 同步状态访问应用 连接 GitOps 工作流体验 GitOps 工作流生产建议1&#xff09;修改默认密码2&#xff09;配置 Ingress 和 TLS3&#xff09;使用 Webhook 触发 ArgoCD4&#xff09;将源…

【C++】开源:Boost网络库Asio配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Asio网络库配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次…

手机怎么把网址转二维码?网址活码手机端制作教学

相信很多小伙伴都知道电脑生成网址二维码方法&#xff0c;只需要利用二维码生成器&#xff08;二维码生成器-手机二维码制作生成器-免费在线生成二维码-机智熊二维码&#xff09;的网址生成二维码功能&#xff0c;就可以轻松将网址生成二维码。那么大家知道在手机上怎么操作吗&…

兴达易控CANopn 主站转 profinet 网关的网关配置及操作

兴达易控CANopn 主站转 profinet 网关&#xff08;XD-COPNm20&#xff09;做为 PROFINET 网络的 Device 设备&#xff08;即从站&#xff09;&#xff0c;带 2 个 RJ45 以太网接口&#xff0c;支持100BASE-TX&#xff0c;MDI/MDIX 自检测&#xff0c;集成以太网交换机&#xff…

Jenkins 拉取 GitHub 私有仓库失败问题

添加仓库的时候提示 stderr: fatal: Cannot prompt because user interactivity has been disabled. 把在 GitHub账户设置中生成的个人访问令牌填到地址里

使用docker搭建nacos

使用docker搭建nacos docker搭建最新版nacosMySQL下简历nacos配置数据表拉取镜像创建挂载目录启动容器访问nacos docker搭建nacos 2.0版本 docker搭建最新版nacos 最近想在自己服务器上搭建一个nacos服务&#xff0c;以前一直在本地的windows上使用&#xff0c;而且使用着naco…

Rabbitmq的安装与使用(Linux版)

目录 Rabbitmq安装 1.在Ubuntu上安装RabbitMQ&#xff1a; 打开终端&#xff0c;运行以下命令以更新软件包列表&#xff1a; 安装RabbitMQ&#xff1a; 安装完成后&#xff0c;RabbitMQ服务会自动启动。你可以使用以下命令来检查RabbitMQ服务状态&#xff1a; 2.在CentOS…

湖南大学师生一行到访麒麟信安参观交流

7月6日下午&#xff0c;湖南大学信息科学与工程学院师生一行百余人到访麒麟信安参观交流。 在公司展厅&#xff0c;同学们详细了解了麒麟信安的发展历程、产业布局、生态圈建设等方面情况&#xff0c;观摩麒麟信安在国产操作系统等领域的各项研发成果&#xff0c;并参观了麒麟…

【数据结构】二叉树前中后层序遍历代码实现以及各种操作与二叉树OJ题目

目录 一、二叉树的遍历 1、前序遍历 2、后续遍历 3、中序遍历 二、二叉树简单的操作 1、计算节点个数 1.二叉树所有节点个数 2.二叉树叶子节点个数 3.二叉树第K层节点个数 2、二叉树的高度 3、二叉树是否存在key 1.二叉树中是否存在key 2.寻找二叉树中key节点 三、…

这些你值得拥有的音频转文字软件推荐给你

小明是一个音乐爱好者&#xff0c;他热爱听歌。然而&#xff0c;有一天&#xff0c;他突然失去了听力&#xff0c;这令他感到沮丧和无助&#xff0c;他再也无法知晓音乐的内容了。正当小明陷入困境时&#xff0c;他听说了一个神奇的技术——音频转文字。这项技术据说可以将音频…

Leetcode周赛 | 2023-7-24

2023-7-24 题1体会我的代码 题2这道题是一点都不会重点我的代码 题3重点我的代码 题二题三都不会621. 任务调度器思路 题1 体会 想到倒序遍历就可以。 我的代码 class Solution:def maxArrayValue(self, nums: List[int]) -> int:n len(nums)i n-1while i > 0 :if n…

CSS背景虚化

.mark{background-color: rgba(0,0,0,.1);-webkit-backdrop-filter: blur(3px);backdrop-filter: blur(3px); }backdrop-filter CSS 属性可以让你为一个元素后面区域添加图形效果&#xff08;如模糊或颜色偏移&#xff09;。 因为它适用于元素背后的所有元素&#xff0c;为了看…

MYSQL 高级SQL语句(二)

目录 一、表连接查询 1.1 left join&#xff08;左连接&#xff09; 1.2 right join&#xff08;右连接&#xff09; 1.3 inner join&#xff08;内连接&#xff09; 二、视图 2.1 视图表与派生表比较 一、表连接查询 MYSQL数据库中的三种连接&#xff1a; inner join(内…

pytorch分类和回归:阿里天池宠物年龄预测

文章目录 dog年龄预测论文Deep expectation of real and apparent age from a single image without facial landmarks分类的损失函数1.多分类交叉熵损失函数&#xff1a;2.KLDiv Loss&#xff1a; 分布差异3.facenet 三元组损失函数 timm and torchvisiontorchvision 尝试一&a…