数据结构子KMP算法

news/2024/4/18 11:44:42/文章来源:https://blog.csdn.net/y_k_j_c/article/details/127149967

传统从主串找子串方法

在这里插入图片描述
然子串从第一个开始,一个个比对,相同比对第二个字母
不同然子串后移一位重新开始比较
直至找到全部相同的或者主串里面没有让子串比较的字母了

这样的算法太暴力,执行效率太低

KMP算法

来说我们人脑对于字符串匹配的思考方式吧
从左往右直接扫
不会说回去再看一遍

那怎么让代码完成这样的操作呢?

在这里插入图片描述
那就是KMP算法喽

回溯子子串不回溯主串
在这里插入图片描述

直接右移五步
在这里插入图片描述
若11是g在这里插入图片描述
若11不是j
在这里插入图片描述

但是到底子串要从主串的哪个位置开始比较是不固定的
在这里插入图片描述
如果死第五个字母不匹配
要从第四个字母开始比较
而不是从不匹配的字母开始匹配了

那么如果比较失败到底从主串哪里重新开始匹配呢?

需要另外定义一个next数组看到第几个不匹配然后
在取对应数字next数组的元素
子串的对应位置开始再次比较
(因为主串指针不回溯,所以next里面是存放的是子串的位置)
在这里插入图片描述
j是指向子串的从1开始
i指向主串

对应代码

在这里插入图片描述
next[1]=0;
第一个位置就不同,使j=0
然后i++,j++
子串重新指到1
然后主串后一一位

那么如何求一个模式串的next数组呢?

求next数组

手算

当j=6匹配失败应该从第个开始?
就拿子串依次次往后移呗
看有没有可以和前面对应的
对应了i个那么next[j]=i+1

在这里插入图片描述
对应了(此时j还是6)
对应了2个那么next[6]=3
在这里插入图片描述
这个也是同理

在这里插入图片描述

总结(方法)

在这里插入图片描述

比如说下面
第7个字符匹配失败,然后把对应的第1-6字符组成一个字符串
看这个字符串前缀和对应上面1-6进行匹配
一定是看对应的
上面串的后缀

下面串的前缀
(上面不含头,下面不含尾)最长相等长度哦
(就是让下面的往右移直至到第一次相同,就是最长长度,不包含刚开始的时候)
如果都不匹配,那就是0+1=1呗

一些特殊情况

如果一开始就不匹配(第一个位置)
那么next[1]固定是0,这个情况下实行i++和j++

如果第二个不匹配
这个时候其实取
1-j-1元素那就是第一个元素
就一个元素
这个元素既是前缀又是后缀
但是要求不能包含下面串的后缀
所以
此时next[2]=1(固定的)

我的一些小方法

就是看第i个匹配失败
取出对应模式串1-i-1(取两次)
然后和自己比较
看1-i-1
比如
ababaa
第三匹配失败
取
ab
ab
上面取后缀,下面前缀
下面往右移
abab
还是不相同
abab
最后没有相同的,重新开始比较呗
next[3]=1
比如第四个失败
取的是
aba
aba
下面的开始右移
abaaba
不同
abaaba
此时对应位置相同了
则next[4]=1+1=2

在这里插入图片描述

在这里插入图片描述

代码实现

在这里插入图片描述

时间复杂度

在这里插入图片描述

进一步优化

在这里插入图片描述
例如这个情况
下一步就是把j=1

在这里插入图片描述

这个过程有没有感觉有一丝多余
因为你的子串第四个字符和第一个字符就相同
第四个不匹配
所以主串的对应字符不是g
所以你就算把j=1然后比较也肯定不相同
这就多了一次比较

对应优化
在这里插入图片描述

怎么求next_value

在这里插入图片描述
看左下角
首先有next数组
然后从左往右比
看从2开始看
第二个序号j的next
指向第一个字符(a)
但是它自己对应也是a
所以把对应第一个序号对应的数组(0)
赋给第二个序号对应的nextvalue
第三个也是
第四个也是
第五个的话对应的next为4
第四个字符和第五个字符不同
所以
保存对应的next到nextvalue
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux第三章——用户与组管理

用户与组账号 一个用户可以隶属于不同的组一个组可以包含若干用户系统通过账户对用户与组进行管理 账号 Linux系统账号分为用户账号和组账号 用户账号:每个系统的操作者拥有一个用户账号,每个用户账号具有唯一的标识UID和自己所属组的标识GID。组账号…

【Android-JetpackCompose】5、三阶段:组合、布局、绘制,架构分层,设计原则、性能最佳实践

文章目录一、帧的3个阶段1.1 第 1 阶段:组合1.2 第 2 阶段:布局1.3 第 3 阶段:绘制二、读取 state2.1 优化读取 state三、重组循环(循环阶段依赖项)四、架构分层五、设计原则5.1 控制5.2 自定义六、性能最佳实践6.1 使…

c++类和对象

前言 在学习完漫长的C语言,那么这篇文章也算是开始踏上了高级语言之路 。古人云:路漫漫其修远兮,吾将上下而求索。c的道路才开始,那么我们应该为此开始思考了。余甚 愚,余认为c有太多细节了,必定耗时细磨才…

实验一:贝叶斯神经网络及其如何用随机梯度马尔可夫链蒙特卡洛有效训练

0.实验环境搭建: 源代码获取: 来源一:google 来源二:web 来源三:github 环境: conda create --name python36_google_deep python3.6 conda activate python36_google_deep #建议按照顺序安装 pip inst…

基于FPGA的图像边缘检测

基于FPGA的图像边缘检测一、图像处理算法1.灰度转换2.高斯滤波3.二值化4.Sobel二、项目框架1.摄像头配置模块2.图像处理模块3.数据缓存模块4.其它模块三、部分代码1.数据采集模块2.读写控制模块四、参考五、源码简介:基于FPGA,摄像头实时采集图像数据&am…

【Algorithm】Karatsuba Multiplications 乘法算法

Karatsuba Multiplications Q1: 请计算:x1234x1234x1234, y5678y5678y5678, x∗y?x*y?x∗y? 这个问题其实我们在三年级的时候就学过,用乘法竖式进行运算。但是有没有其他的方法,或者说,如果 x,yx,yx,y 非常大的时候…

drf 视图类 GenericAPIView 及扩展

drf 视图类 GenericAPIView 及扩展 文章目录drf 视图类 GenericAPIView 及扩展1、2个视图基类1.1、GenericAPIView:属性和方法1.2、基于APIView 写5个接口1.3、基于GenericAPIView写5个接口2、5个视图扩展类2.1 基于GenericAPIView5个视图扩展类写接口3、九个视图子…

【UCB操作系统CS162项目】Pintos Lab2:用户程序 User Programs(下)

在上节中,我们已经完成了 Lab 2 要求的参数传递和系统调用中的 halt, exit 以及向 stdout 输出的 write,最终停在了 wait 的实现之前。本节就先从 wait 和 exec 继续。 Syscall wait exec:实现父子进程 讲义中 wait 的要求是这样的&#x…

这几个文字翻译工具确定不试试看?

想问问大家平常会接触到TXT文件吗?这是微软在操作系统上附带的一种文本格式,主要是保存纯文字信息,像我们电脑上自带的记事本工具,就是使用这种文件格式。有时候我们需要将文本内容翻译成中文。那你知道如何实现TXT翻译成中文吗&a…

LRU缓存——哈希表+双向链表

一、题目描述 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: 1)LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 2)int get(int key) 如果关键字 key 存在于缓存中,…

STA系列 - 特殊时序分析multicycle/half-cycle/false path

文章目录什么是require time/arrive timeMulticycle PathHalf PathFalth Path本篇文章介绍的是特殊的时序path, 全文为视频笔记,以及自己的理解https://www.bilibili.com/video/BV1if4y1p7Dq?p10&vd_source84d1070e8334ce7e2bb0bd110abcf1a7什么是require time…

使用服务器跑模型——案例2

案例2 在本案例中我们使用vscode来上传/下载文件,服务器端编程和debug。 下载 vscode 在官网下载vscode正式版,别使用家庭版。下载地址https://code.visualstudio.com/Download。 使用 vscode 连接服务器 在vscode扩展中搜索ssh并下载安装。 安装成功…

【机器学习】熵权算法确定权重 原理+完整MATLAB代码+详细注释+操作实列

【机器学习】熵权算法确定权重 原理完整MATLAB代码详细注释操作实列 文章目录 1. 熵权法确定指标权重 (1)构造评价矩阵 Ymn (2)评价矩阵标准化处理 (3)计算指标信息熵值 Mj (4&#xff09…

原生JS项目练习——验证码的生成及教验

一、主要功能介绍: 1、通过for循环生成生成六位随机验证码 2、通过for循环随机生成验证码颜色 3、窗口加载事件,窗口一加载就调用函数,重置验证码 4、按钮点击事件,一点击就调用函数,重置验证码 5、input输入框已失去焦…

Yarn概述

Hadoop系列 注:大家觉得博客好的话,别忘了点赞收藏呀,本人每周都会更新关于人工智能和大数据相关的内容,内容多为原创,Python Java Scala SQL 代码,CV NLP 推荐系统等,Spark Flink Kafka Hbase…

公众号网课搜题接口系统

公众号网课搜题接口系统 本平台优点: 多题库查题、独立后台、响应速度快、全网平台可查、功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 查题校园题库:查题校园题库后台(…

快速开发微信小程序之二-微信支付

一、背景 在面试程序员的时候,有两项经历会带来比较大的加分,第一你是否做过支付金融相关的业务,第二你是否写过底层框架中间件代码,今天我们聊一下微信支付是如何对接的。 二、相关概念 1、微信商户平台 要使用微信支付&#…

一、mini2440_bsp_led

一、芯片手册 1、板子原理图 2、GPIO使用 (1)GPxCON (2)GPxDAT 二、实现分析 1、初始化led 设置GPBCON(0x56000010)为 0x00015400 2、设置led输出,根据原理图引脚输出低电平时灯被点亮 LED1…

K8s-临时容器 Ephemeral Containers

临时容器 Ephemeral Containers 当由于容器崩溃或容器镜像不包含调试工具而导致 kubectl exec 无用时, 临时容器对于交互式故障排查很有用。尤其是,Distroless 镜像 允许用户部署最小的容器镜像,从而减少攻击面并减少故障和漏洞的暴露。 由于…

C | 枚举?看一遍就够了

CSDN话题挑战赛第2期 参赛话题:学习笔记 啊我摔倒了..有没有人扶我起来学习.... 目录前言枚举1. 枚举的定义2. 枚举的内存大小3. 枚举的优势4. 枚举需要注意的地方前言 结构体、枚举、联合体都是自定义类型,结构体主要知识点结构体内存对齐可参考《C | …