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_最大公共前后缀代码实现_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1iJ411a7Kb?p=5&vd_source=a934d7fc6f47698a29dac90a922ba5a3

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

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

相关文章

Java架构师缓存性能优化

目录 1 缓存的负载策略2 缓存的序列化问题3 缓存命中率低4 缓存对数据库高并发访问5 缓存数据刷新的策略5.1. 实时策略5.2. 异步策略5.3. 定时策略6 何时写缓存7 批量数据来更新缓存8 缓存数据过期的策略9 缓存数据如何恢复10 缓存数据如何迁移11 缓存冷启动和缓存预热想学习架…

解决react样式组合时css module动态样式失效的问题

现象&#xff1a; <button disabled{invalid} className{ "btn btn-primary btn-lg" invalid ? styles.btnDisabled : "" } > 注册 </button> 上面采用字符串拼接的方式&#xff0c;组合class&#xff0c;但是css module的动态样式style…

【Java零基础入门到就业】第一天:java简介和cmd窗口的一些常见命令

1、java简介 Java是一种基于类的、面向对象的编程语言&#xff0c;它被设计成具有尽可能少的实现依赖。它旨在让应用程序开发人员编写一次&#xff0c;并在任何地方运行(WORA)&#xff0c;这意味着编译后的Java代码可以在所有支持Java的平台上运行&#xff0c;而无需重新编译。…

【具身智能模型1】PaLM-E: An Embodied Multimodal Language Model

论文标题&#xff1a;PaLM-E: An Embodied Multimodal Language Model 论文作者&#xff1a;Danny Driess, Fei Xia, Mehdi S. M. Sajjadi, Corey Lynch, Aakanksha Chowdhery, Brian Ichter, Ayzaan Wahid, Jonathan Tompson, Quan Vuong, Tianhe Yu, Wenlong Huang, Yevgen C…

Vue鼠标右键画矩形和Ctrl按键多选组件

效果图 说明 下面会贴出组件代码以及一个Demo&#xff0c;上面的效果图即为Demo的效果&#xff0c;建议直接将两份代码拷贝到自己的开发环境直接运行调试。 组件代码 <template><!-- 鼠标画矩形选择对象 --><div class"objects" ref"objectsR…

bash一行输入,多行回显demo脚本

效果图&#xff1a; 脚本&#xff1a; #!/bin/bash # 定义一个变量&#xff0c;用来存储输入的内容 input"" # 定义一个变量&#xff0c;用来存储输入的字符 char""# 为了让read能读到空格键 IFS_store$IFS IFS# 提示内容&#xff0c;在while循环中也有&a…

CSS 滚动驱动动画 animation-range

animation-range 语法 normallength-percentagetimeline-range-name 具名时间线范围 named timeline rangecovercontainentry 和 entry-crossingexit 和 exit-crossing 兼容性 animation-range 这个属性可同时对 scroll progress timeline 和 view progress timeline 这两种不…

数据结构与算法-(8)---队列(Queue)

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

Python算法练习 10.15

leetcode 2130 链表的最大孪生和 在一个大小为 n 且 n 为 偶数 的链表中&#xff0c;对于 0 < i < (n / 2) - 1 的 i &#xff0c;第 i 个节点&#xff08;下标从 0 开始&#xff09;的孪生节点为第 (n-1-i) 个节点 。 比方说&#xff0c;n 4 那么节点 0 是节点 3 的孪…

LaunchView/启动页 的实现

1. 创建启动画板&#xff0c;LaunchScreen.storyboard 添加组件如图: 2. 项目中设置只支持竖屏&#xff0c;添加启动画板&#xff0c;如图: 3. 创建启动画面动画视图&#xff0c;LaunchView.swift import SwiftUI/// 启动视图 struct LaunchView: View {/// 字符串转换为字符串…

ES知识点全面整理

● 我们从很多年前就知道 ES6, 也就是官方发布的 ES2015 ● 从 2015 年开始, 官方觉得大家命名太乱了, 所以决定以年份命名 ● 但是大家还是习惯了叫做 ES6, 不过这不重要 ● 重要的是, ES6 关注的人非常多, 大家也会主动去关注 ● 但是从 2016 年以后, 每年官方都会出现新…

【TensorFlow2 之013】TensorFlow-Lite

一、说明 在这篇文章中&#xff0c;我们将展示如何构建计算机视觉模型并准备将其部署在移动和嵌入式设备上。有了这些知识&#xff0c;您就可以真正将脚本部署到日常使用或移动应用程序中。 教程概述&#xff1a; 介绍在 TensorFlow 中构建模型将模型转换为 TensorFlow Lite训练…

Mac 远程 Ubuntu

1. Iterm2 添加ssh 参考&#xff1a;https://www.javatang.com/archives/2021/11/29/13063392.html 2. Finder 添加远程文件管理 2.1 ubuntu 配置 安装samba sudo apt-get install samba配置 [share]path /home/USER_NAME/shared_directoryavailable yesbrowseable ye…

NewStarCTF2023week2-ez_sql

闭合之后尝试判断字段数&#xff0c;存在WAF&#xff0c;使用大小写绕过&#xff08;后面的sql语句也需要进行大小写绕过&#xff09; ?id1 Order by 5-- 测出有5列 ?id1 Order by 6-- 查一下数据库名、版本、用户等信息 ?id1Union Select database(),version(),user(),4,…

elementUI el-table+树形结构子节点选中后没有打勾?(element版本问题 已解决)

问题 1.不勾选父级CB111&#xff0c;直接去勾选子级&#xff08;ST2001…&#xff09;&#xff0c;子级选中后没有打勾显示 排查 一直以为是这个树形结构和表格不兼容产生的问题&#xff0c;到后来看官方demo都是可以勾选的&#xff0c;最后排查到了版本问题&#xff0c; 项…

数学建模——人工神经网络模型

一、人工神经网络简介 1、神经网络起源与应用 1943年心理学家McCulloch和数学家Pitts提出神经元生物数学模型&#xff08;M-P模型&#xff09;&#xff0c;后来人工神经网络(Artifical Neural Network,ANN)是在生物神经网络(Biological Neural Network,BNN)基础上发展起来的&a…

SystemC入门学习-第8章 测试平台的编写

之前的章节&#xff0c;一直把重点放在用SystemC来描述硬件电路上&#xff0c;即如何编写SystemC 的RTL。本章的注意力集中在验证和编写测试平台上。 重点包括&#xff1a; 如何生成时钟信号和激励波形如何编写有响应能力的测试平台如何记录仿真结果 8.1 编写测试平台 测试平…

IO流:java中解码和编码出现乱码说明及代码实现

IO流&#xff1a;java中解码和编码的代码实现 一、UTF-8和GBK编码方式二、idea和eclipse的默认编码方式三、解码和编码方法四、代码实现编码解码 五、额外知识扩展 一、UTF-8和GBK编码方式 如果采用的是UTF-8的编码方式&#xff0c;那么1个英文字母 占 1个字节&#xff0c;1个…

使用Swift开发Framework遇到的问题及解决方法

文章目录 一、Swift 旧版本Xcode 打出来的framework 新版本不兼容问题 一、Swift 旧版本Xcode 打出来的framework 新版本不兼容问题 Cannot load module xxx built with SDK ihphoneos16.4 when using SDK iphoneos17.0:XXX/xxx.framework/Modules/xxx.swiftmodule/arm64-appl…

java swing实现点击按钮切换图片(简单实现)

本文教程&#xff0c;主要提供一个简单的例子&#xff0c;使用java swing完成点击按钮能够切换图片。 目录 一、程序预览 二、程序代码 一、程序预览 二、程序代码 package learnProject.csdn;import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.ev…