KMP 算法 + 详细笔记
给两个字符串,T="AAAAAAAAB",P="AAAAB";
可以暴力匹配,但是太费时和效率不太好。于是KMP问世,我们一起来探究一下吧!!!
(一)最长公共前后缀
- D[i] = p[0]~p[i] 区间(前i+1个字母)所拥有的最大......的长度
- D[0]=0,表示p[0]~p[0]区间(前1个字母)->也就是 A 所拥有的最长公共前后缀长度为0.
- D[1]=1,表示p[0]~p[1]区间(前2个字母)->也就是 AA 所拥有的最长公共前后缀长度为1.
- D[2]=2,表示p[0]~p[2]区间(前3个字母)->也就是 AAA 所拥有的最长公共前后缀长度为2.
- D[3]=3,表示p[0]~p[3]区间(前4个字母)->也就是 AAAA 所拥有的最长公共前后缀长度为3.
- D[4]=0,表示p[0]~p[4]区间(前5个字母)->也就是 AAAAB 所拥有的最长公共前后缀长度为0.
我们先手算好了P="AAAAB"的D[i]数组(记录最长公共前后缀),继续挖掘,看看有没有好东西!
(1)举个栗子,T = "AAAAAAAAB",P="AAAAB" ,D[i]数组上文已经求出
当 i = 4,j = 4 时,T串 和 P串 发生不匹配,此时我们就发现 T[0-3] 和 P[0-3] 是完全匹配的,那就会思考:是否可以用一些方法来跳过已经判断是能匹配的范围呢?
在 j = 4时,j-1=3,D[3] = 3,也就是意味着P[0]~P[3] 区间(前4个字母)所拥有的最大公共前后缀长度为3.
于是从图中我们可以看到标注为① ② ③ ④ 条红色的线,表示 T 和 P的前后缀相同
着重看②和③这两条,我们可以让 j = 3,即进行操作是:j = D[4-1]; 再让T[i] 和 P[j] 去判断是否匹配。
此时 i = 4 , j = 3时,T[4] = P[3],是匹配的,那么让 i++, j++,可得到下图:
此时 i = 5 , j = 4时,T[5] ≠ P[4],是不匹配的,此时跟前面的操作一样。进行操作是:j = D[4-1]; 再让T[i] 和 P[j] 去判断是否匹配。可得到下图:
此时 i = 5 , j = 3时,T[5] = P[3],是匹配的,那么让 i++, j++,可得到下图:
此时 i = 6 , j = 4时,T[6] ≠ P[4],是不匹配的,此时跟前面的操作一样。进行操作是:j = D[4-1]; 再让T[i] 和 P[j] 去判断是否匹配。可得到下图:
此时 i = 6 , j = 3时,T[6] = P[3],是匹配的,那么让 i++, j++,可得到下图:
此时 i = 7 , j = 4时,T[7] ≠ P[4],是不匹配的,此时跟前面的操作一样。进行操作是:j = D[4-1]; 再让T[i] 和 P[j] 去判断是否匹配。可得到下图:
此时 i = 7 , j = 3时,T[7] = P[3],是匹配的,那么让 i++, j++,可得到下图:
此时 i = 8 , j = 4时,T[8] = P[4],是匹配的,那么让 i++, j++,可得到下图:
此时 i = 9(越界), j = 5(越界),终止!
总结:发现已经匹配成功的部分,它所拥有的最大公共前后缀就不用重复进行比较了,不用再花费无效的时间进行比较了,最大公共前后缀越长,那它所省略的就越多,效率也就越高。相对于暴力匹配来说,效率提升也就越高。
kmp核心思路的关键所在:
- 1.必须理解 D[j] 的意义:P串的前 j+1个字母,即 P[0]~P[j] 所拥有的最大公共前后缀
- 2.匹配到T[i] != P[j]失败时,想一想P[j]是不是P串的第j+1个字母,是不是也意味着:P[0]~P[j-1]的这前j个字母已经匹配成功了
- 3.P[0]~P[j-1]的这前 j 个字母的最大公共前后缀 = D[j-1]
----来自B站Up邋遢大王233的评论区回复
(二)KMP Code
- D[i] = P[0]至P[i],P串前 i+1 个字母拥有的最大公共前后缀的长度
D[k] 表示 P[0]~P[k]时,前 k+1 个 字母拥有的最大公共前后缀的长度
同理,D[j-1]: P[0]~P[j-1], 前 j 个 字母拥有的最大公共前后缀的长度
结合上图,D[j-1]:P[0]~P[j-1],前 j 个 字母拥有的最大公共前后缀的长度
在上图我们知道,在 i 位置的 x 和 j 位置的 y 匹配失败。此时该怎么办呢?为了更好的观察规律,我们不妨设D[j-1] = 3,也就是说P[0]~P[j-1],前 j 个 字母拥有的最大公共前后缀的长度为3。此时如下图:
那么让 j = D[j-1] = 3,此时 j 的位置 更新到下标为3这个位置,再从j = 3这个位置与 T 串的 x进行匹配判断
若 j = 0时,匹配失败。此时再让 j = D[j-1]是无意义的。已经越界了。那怎么办呢?
若 j = 0时,匹配失败。让 j 不变,i++
j == np (视频中没有介绍后续如何继续匹配,所以一旦匹配成功一次就结束算法了)。而匹配失败时j只可能减少不可能增加第一次匹配成功后,后续想要继续的话,继续 j = D[j-1] 就可以了(此时必然 j = np ,所以写成 j=D[np-1] 也对) ----来自B站Up邋遢大王233的评论区回复
未完待续,明天继续编辑~
参考和推荐视频:kmp_5_最大公共前后缀代码实现_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1iJ411a7Kb?p=5&vd_source=a934d7fc6f47698a29dac90a922ba5a3
相关文章:

KMP 算法 + 详细笔记
给两个字符串,T"AAAAAAAAB",P"AAAAB"; 可以暴力匹配,但是太费时和效率不太好。于是KMP问世,我们一起来探究一下吧!!! (一)最长公共前后缀 D[i] p[…...

基于主动移频法与AFD孤岛检测的单相并网逆变器matlab仿真
微❤关注“电气仔推送”获得资料(专享优惠) 仿真模型 算法介绍 (1)仿真模型由单相电网、逆变器、滤波环节、PI控制器、PWM生成器、锁相环、AFD控制器s函数、测量模块等构成; (2)采用主动移频法(AFD)进行孤岛检测; (3)相应速度…...

MIT 6.S081 Operating System/Fall 2020 macOS搭建risc-v与xv6开发调试环境
文章目录 本机配置安装环境Homebrew执行安装脚本查看安装是否成功 RISC-V tools执行brew的安装脚本 QEMUXV6 测试有用的参考链接(感谢前辈)写在结尾 本机配置 电脑型号:Apple M2 Pro 2023 操作系统:macOS Ventura 13.4 所以我的电…...

JMeter定时器
一. 同步定时器(Synchronizing Timer) (在Loadrunner中叫做集合点) 思考: 如何模拟多个用户同时抢一个红包?如何测试电商网站中抢购活动、秒杀活动? 1.1 介绍 Sync Timer的目的是阻塞线程,直…...

zookeeper应用场景(二)
单机环境下可以利用jvm级别的锁,比如synchronized、Lock等来实现锁,如果是多机部署就需要一个共享数据存储区域来实现分布式锁 一、分布式锁实现方式 1、基于数据库实现分布式锁 可以用数据库唯一索引来实现 2、基于redis实现分布式锁 redis实现的分…...
Android webView加载高德地图定位不显示问题
如果只显示地图 val webView: WebView findViewById(R.id.webView)webView.settings.javaScriptEnabled truewebView.loadUrl("https://test.cn")//h5地址 如果需要定位,则需要加以下代码,否则不弹窗 webView.webChromeClient object : We…...

94. 二叉树的中序遍历(递归+迭代)
题目链接:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 解题思路: 方法一:递归 中序遍历的操作定义为,若二叉树为空,则空操作,否则: 中序遍历左子树访问根节点中…...

UGUI交互组件Slider
一.Slider对象的结构 对象介绍Slider附加Slider组件Background背景Fill Area填充范围Fill填充对象Handle Slider Area滑块移动范围Handle滑块 二.Slider组件属性 属性说明Fill Rect关联填充对象Handle Rect关联滑块对象Direction设置方向Min Value最大取值Max Value最小取值Wh…...
JAVA经典百题之按位或运算符 `|的使用
当学习Java语言中的按位或运算符 | 时,需要理解其用途、应用场景、示例源代码以及相应的注意事项。以下是一篇关于Java语言按位或运算符的详细文章,包括示例源代码和注释。 Java语言中的按位或运算符 | 按位或运算符 | 是Java语言中用于对二进制位进行…...
C多线程编程- 近似求解π
本程序使用蒙特卡洛方法估算圆周率(π)。它首先创建了指定数量的线程,每个线程生成一个随机点并检查该点是否在单位圆内。基于这些线程的结果,程序计算在单位圆内的点的比例,并乘以4来估算π的值。为了对比,…...
YOLOV7量化第二步: 模型标定
2.模型标定 当然可以,模型量化中的标定(calibration)是一个关键过程,它主要确保在降低计算精度以减少模型大小和提高推理速度的同时,不会显著损害模型的准确性。现在,我将根据您提供的步骤解释这一过程。 …...

前端-uniapp-开发指南
美团外卖微信小程序开发 uniapp-美团外卖微信小程序开发P1 成果展示P2外卖小程序后端,学习给小程序写http接口P3 主界面配置P4 首页组件拆分P13 外卖列表布局筛选组件商家 布局测试数据创建样式 请求商家外卖数据封装请求并发请求 uni-app框架调用https接口 开发小程…...

Java集合类ArrayList的应用-杨辉三角的前n行
目录 一、题目 杨辉三角 二、题解 三、代码 四、总结 一、题目 题目链接:https://leetcode.cn/problems/pascals-triangle/description/ 杨辉三角 题目描述:给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨…...

C语言-函数
函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() 。 主函数可以调用其他函数,其他函数也可以相互调用,用户也可以那个自定义函数。 函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实…...

蓝桥杯 枚举算法 (c++)
枚举就是根据提出的问题,——列出该问题的所有可能的解,并在逐一列出的过程中,检验每个可能解是否是问题的真正解, 如果是就采纳这个解,如果不是就继续判断下一个。 枚举法一般比较直观,容易理解࿰…...

Wordpress自定义小工具logo调用设置(可视化)
在主题开发中,需要调用网站的logo,最简单的办法就是用wp自带的函数,那就是the_custom_logo(),使用它还可以通过后台-自定义-logo,边修改边预览,还是很香的。 自定义徽标支持应首先使用add_theme_support()添…...

面试常考数据结构:红黑树、B树、B+树各自适用的场景
1. 磁盘基础知识 分页: 现代操作系统都使用虚拟内存来印射到物理内存,内存大小有限且价格昂贵,所以数据的持久化是在磁盘上。虚拟内存、物理内存、磁盘都使用页作为内存读取的最小单位。一般一页为4KB(8个扇区,每个扇…...

Paddle GPU版本需要安装CUDA、CUDNN
完整的教程 深度学习环境配置:linuxwindows系统下的显卡驱动、Anaconda、Pytorch&Paddle、cuda&cudnn的安装与说明 - 知乎这篇文档的内容是尽量将深度学习环境配置(使用GPU)所需要的内容做一些说明,由于笔者只在windows和linux下操作过…...
MYSQL length函数
mysql length函数计算结果的单位是啥,和varchar字段类型的单位是相同的吗? 做了一下实验,结果如下: 1.mysql length 函数计算的是有多少个字符,比如字段值是 permission 则length函数计算结果为10。 2.如果字段类型是…...
uniapp 在android手机上运行tab栏页面跳转问题
【问题描述】: 使用uniapp写的项目,在tab页面,无论使用哪种方式的跳转,只要是在url后面拼接参数,在打包成apk文件后,在手机上面安装使用,都是获取不到susIndex参数的,而在浏览器上面…...

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...

VB.net复制Ntag213卡写入UID
本示例使用的发卡器:https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...