【KMP算法】学习总结

说明

  1. 文章内容为对KMP算法的总结,以及力扣例题;
  2. 文章内容为个人的学习总结,如有错误,欢迎指正。

文章目录

  • 1. KMP算法
    • 1.1 算法步骤
    • 1.2 关于指针回退问题
  • 2 . LeetCode例题

1. KMP算法

1.1 算法步骤

KMP算法通常用于字符串的匹配,解题分两步:

  1. 构建模式串的next数组。
    一般来说next数组就是前缀表(不太准确,但差不多是那个意思)。next[i]表明当第i个元素不匹配时应该回退到哪个位置:
    比如第i个元素不匹配,此时应寻找i之前的子串的最长相同前后缀的长度,这个长度的值就是next[i-1]的值。
    例:aab当i指向‘b’是发生了失配,此时应寻找b之前的子串,即‘aa’的最长相同前后缀的长度(=1),也就是说此时i指针应回退到下标为1的位置继续比较
  2. 匹配
    即模式串与主串的匹配。两个指针i,j分别指向主串和模式串,若二者匹配则两个指针后移;若发生失配,则指向模式串的指针j进行回退,重新匹配。

1.2 关于指针回退问题

关于指针回退的问题,我梳理一下:
例如:

主串='aabaabaaf'
模式串='aabaaf'

在这里插入图片描述

  1. 匹配时,模式串的‘f’与主串的‘b’不匹配,此时模式串的指针应该回退,但是回退到哪个位置呢?KMP算法告诉我们应该回退到模式串‘b’的位置,为什么呢?

  2. 因为不匹配的‘f’之前的子串——‘aabaa’的最长相同前后缀长度为2,即‘b’的下标。‘f’失配,但是‘aabaa’是和主串相匹配的,也就是说模式串中的“aa”(下标为3,4)与主串中的“aa”(下标为3,4)是相匹配的,而且子串“aabaa”中,后缀“aa”有最长相同的前缀“aa”(下标为0,1),也就是说这个前缀“aa”(下标0,1)和主串中的“aa”(下标为3,4)也是相匹配的,所以无需重复比较,直接将指针回退到模式串的‘b’位置继续比较即可。
    在这里插入图片描述

  3. 所以next[i]中存储的是i以及i以前的子串的最长相同前后缀长度。那么当i发生失配时,就要找i以前(0~i-1)的子串的最长相同前后缀长度是多少,然后回退到这个位置。
    比如‘f’失配时,要找‘f’之前的子串的最长相同前后缀长度(aabaa的最长相同前后缀长度)

2 . LeetCode例题

28. 找出字符串中第一个匹配项的下标

class Solution {
public:int strStr(string haystack, string needle) {vector<int> next(needle.size(),0);getNext(next, needle); //创建needle的next数组int j=0;for(int i=0; i<haystack.size(); i++){while(j>0 && haystack[i]!=needle[j])j = next[j-1];//发生失配,j进行回退if(haystack[i] == needle[j])j++;if(j == needle.size())return (i - needle.size() +1);//主串中出现了模式串,返回第一次出现模式串的下标}return -1; //主串中没有出现模式串,返回-1}void getNext(vector<int>& next, string needle){int n = needle.size();int j = 0; //j指向前缀的末尾next[0] = 0;//初始化nums[0]for(int i=1; i<n; i++){//j从0开始,则i从1开始,i指向后缀的末尾,初始前后缀的长度都是1while(j>0 && needle[i]!=needle[j])j = next[j-1];//前后缀的末尾不匹配,j指针进行回退//j指针的回退相当于减小前缀的长度,当前缀末尾和后缀末尾相同时,此时就找到了needle[i](包括needle[i])之前的最长相同前后缀的长度;否则最长相同前后缀长度为0if(needle[i] == needle[j]){j++; //前后缀末尾相同时,同时后移i,j指针}next[i] = j;//将j的位置赋值给next[i],表明第i个元素发生失配时应该回退到哪个位置}}
};

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

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

相关文章

springboot_vue知识点

代码放到了仓库。 springboot_vue知识点 1.搭建1.vue2.springboot 2.前后端请求和响应的封装1.请求封装2.响应封装 3.增删改查1.查询2.分页3.新增和编辑4.删除 4.跨域和自定义异常5.JWT鉴权1.配置pom2.拦截前端请求的拦截器3.生成token并验证token4.登录后生成token5.前端获取…

git如何查看配置,修改配置,设置配置

# 显示当前的Git配置 $ git config --list# 编辑Git配置文件 $ git config -e [--global]# 设置提交代码时的用户信息 $ git config [--global] user.name "[name]" $ git config [--global] user.email "[email address]"

Grafana如何实现折线柱状图

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

竞赛选题 车位识别车道线检测 - python opencv

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习 机器视觉 车位识别车道线检测 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f947;学长这里给一个题目综合评分(每项满分5分) …

从六个方面对比Go和Python的差异

您是否想过 Go 与 Python 之间的主要区别是什么&#xff1f;随着对软件开发人员的需求不断增加&#xff0c;选择哪种编码语言可能会很困难。 ​ 在此&#xff0c;我们将从六个方面对比Go和Python,探讨 Go 和 Python之间的差异。我们将讨论它们的特点、优缺点&#xff0c;以便…

GPT、GPT-2、GPT-3论文精读笔记

视频&#xff1a;GPT&#xff0c;GPT-2&#xff0c;GPT-3 论文精读【论文精读】_哔哩哔哩_bilibili MAE论文&#xff1a;把bert用回计算机视觉领域 CLIP论文&#xff1a;打通文本和图像 GPT 论文&#xff1a;Improving Language Understanding by Generative Pre-Training …

史诗级云故障敲响警钟,应用保障不能没有“连续键”!

近日&#xff0c;知名云服务商出现一次史诗级的云故障&#xff1a;全球所有区域/所有服务同时异常&#xff0c;故障持续长达3小时之多&#xff0c;云上众多应用受到极大影响。 如今&#xff0c;在一个充满不确定性和复杂性的数字化时代&#xff0c;哪怕是顶级云服务商亦不能避…

python-append与extend的区别

append 和 extend 是用于向列表&#xff08;List&#xff09;添加元素的两种不同的方法&#xff0c;它们在功能上有一些重要的区别。 append 方法&#xff1a; append 方法用于在列表的末尾添加单个元素。语法&#xff1a;list.append(element)示例&#xff1a;my_list [1, 2,…

并行与分布式计算 第9章 算法设计

文章目录 并行与分布式计算 第9章 算法设计9.1 设计过程9.1.1 PCAM设计过程9.1.2 划分9.1.3 通信9.1.4 组合9.1.5 映射 8.2 设计方法8.2.1 划分技术9.2.2 分治9.2.3 平衡树技术9.2.4倍增技术9.2.5 流水线技术9.2.6 破对称技术 并行与分布式计算 第9章 算法设计 9.1 设计过程 …

一张图,了解美格智能高算力AI模组

美格智能高算力A模组&#xff0c;澎湃算力让AI触手可及&#xff01;

数字化背景下,集流体行业的智能制造方法论

行业背景 随着全球对清洁能源需求的不断增加&#xff0c;新能源领域正在迅速崛起&#xff0c;在新能源技术中&#xff0c;锂电池作为一种高效、轻便的能量储存解决方案&#xff0c;正成为主流。而锂电集流体作为锂电池的核心部件&#xff0c;承担着电池内部电流分布的关键角色…

掌握Java关键字与面试技巧的完美结合!

问题&#xff1a;请说明什么是策略模式&#xff0c;并使用Java代码举例说明其使用场景和实现方式。 答案&#xff1a; 策略模式是一种行为型设计模式&#xff0c;它允许在运行时根据不同的情况选择不同的算法或策略。它将每个可选的算法封装成一个独立的类&#xff0c;从而使得…

服务号可以迁移到订阅号吗

服务号和订阅号有什么区别&#xff1f;服务号转为订阅号有哪些作用&#xff1f;首先我们要看一下服务号和订阅号的主要区别。1、服务号推送的消息没有折叠&#xff0c;消息出现在聊天列表中&#xff0c;会像收到消息一样有提醒。而订阅号推送的消息是折叠的&#xff0c;“订阅号…

RHEL 8.6 Kubespray 1.23.1 install kubernetes v1.27.7

文章目录 1. 预备条件配置网卡download01 节点安装 nerdctl3. download01 节点 介质下载4. bastion01节点配置 yum 源5. bastion01 离线安装 nerdctl安装l insecure registry配置镜像入库执行 set-all.sh7. bastion01 配置互信8. 启动容器部署环境9. 部署前准备9.1 配置 extrac…

分布式篇---第二篇

系列文章目录 文章目录 系列文章目录前言一、你知道哪些分布式事务解决方案?二、什么是二阶段提交?三、什么是三阶段提交?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你…

基于Pytorch框架多人多摄像头摔倒跌倒坠落检测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 深度学习在计算机视觉领域的应用已经取得了显著的进展&#xff0c;特别是在多人多摄像头场景下的摔倒跌倒检测。通过…

java异常 try/catch/throw/throws

try-catch一般用在最上层的程序里&#xff0c;可以配合throws和throw再将异常抛给用户&#xff0c;这种情况会使上层代码中断。也可以不选择抛出&#xff0c;这种上层代码会继续运行。 被调用的方法如果有异常的可能可以通过throws抛给上层处理&#xff0c;不加try catch的情况…

Vue环境的搭建

1.Vue开发的两种方式 &#xff08;1&#xff09;核心包传统开发模式 基于html/css/js文件&#xff0c;直接引入和辛堡&#xff0c;开发Vue。 &#xff08;2&#xff09;工程化开发模式&#xff1a; 主要是基于构建工具&#xff08;例如,webpack&#xff09;的环境中开发Vue…

【ARM 嵌入式 编译系列 2.2 -- 如何在Makefile 中添加编译时间 | 编译作者| 编译 git id】

请阅读【ARM GCC 编译专栏导读】 上篇文章&#xff1a;【ARM 嵌入式 编译系列 2.1 – GCC 编译参数学习】 下篇文章&#xff1a;【ARM 嵌入式 编译系列 2.3 – GCC 中指定 ARMv8-M 的 Thumb 指令集参数详细介绍】 文章目录 编译参数介绍 编译参数介绍 通常我们在 OS 启动的时…

福州大学《嵌入式系统综合设计》实验五:图像裁剪及尺寸变换

一、实验目的 在深度学习中&#xff0c;往往需要从一张大图中裁剪出一张张小图&#xff0c;以便适应网络输入图像的尺寸&#xff0c;这可以通过bmcv_image_crop函数实现。 实践中&#xff0c;经常需要对输入图像的尺寸进行调整&#xff0c;以适用于网络输入图片尺寸&#xff0…