字符串匹配——烦人的KMP

        相信很多同学看到这篇文章的时候,已经被KMP拿捏了吧!KMP算法说难,倒也不是很难,手算都会,说不难吧,短短几行代码愣是看不懂,辗转反侧,翻书查阅,视频讲解,最后还是一头雾水,百思不得其解(俺也一样.jpg),去年准备初试的时候,学到这里觉得这个算法很神奇,就想搞懂它,但是想了好几天都不太理解,考试也不考代码,就暂且搁置了,奈何复试要上机,故打开力扣刷刷题,开篇就看到KMP,又唤起了我那该死的记忆,昨晚冥思苦想一个半小时,终于悟出正道,来跟大家分享分享……(好久没更博客了,有点话痨)

        还不会手动模拟的同学,可以先去学习一下它的原理,我觉得王道咸鱼学长这个讲得不错4.2_2_KMP算法(旧版上)_哔哩哔哩_bilibili。接下来,完成这道题,就一起反向拿捏这个烦人的KMP吧!


转自力扣

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

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回  -1 

示例 1:

输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。

示例 2:

输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。
提示:1 <= haystack.length, needle.length <= 104haystack和 needle仅由小写英文字符组成​​​​​

理解next数组:

先举个例子理解一下:模式串为ababaa,手算可得出其next数组为:011234,next数组执行如下:

从图中可发现,每次回溯,前面都是有相同匹配的子串,本身匹不匹配不重要(我之前理解是,本身也要匹配,例如,第四位的b回溯到第二位的b,第四位的b前面是aba,第二位的b前面是a,有重复的子串a;第六位的a回溯到第四位的b,第六位的a前面是ababa,第四位的b前面是aba,有重复的子串aba,但a和b并不相等;再来看代码,

void getNext(int next[], string s)
{next[0]=-1;int i=0, j=-1;while(i<s.length()){if(j==-1||s[i]==s[j])//前面都匹配{i++;j++;next[i]=j;}else{j=next[j];}}
}

大家可以想象一下这个场景,拿两个相同的串进行匹配,一前一后,相差一个位置,如果相同,说明到目前为止我都是跟你相同的,而i++、j++,使得 i 指针和 j 指针之前都是相同的(准确的来说是有相同子串),则next[ i ] = j,表示当 i 不匹配的时候,可以跳到 j。如果这两个指针所指的不相等,说明 i 指针和 j 指针之前也是相同的,但是 i 指针和 j 指针失配了,只能让 j = next[ j ],让 j 回溯,j 去找跟它前面相同的,让 i 指针重新和新的 j 指针匹对;重复以上工作……


理解nextval数组:

这个就比next数组容易理解多了,还是拿上面的例子:模式串为ababaa,next数组为:011234,nextval数组为:010104;

例如,当第三位的a失配时,根据next数组要回溯到第一位的a,但是当第三位的a失配时,说明该元素不可能是a,回溯到第一位的a匹配则是多余操作,可以直接跳到它的next;当第六位的a失配时,根据next数组要回溯到第四位的b,因为a失配,只能说明该元素不是a,并不知道它是不是b,所以还要进行匹对;

代码如下:(应该不难理解)

void getNextval(int nextval[], int next[], string s)
{nextval[0]=-1;for(int i=1; i<s.length(); i++){if(s[i]==s[next[i]])//该元素等于next里面的元素,因为字符串的首索引是0{nextval[i]=nextval[next[i]];}else{nextval[i]=next[i];}}
}

最后附上本题的ac代码:

class Solution {
public:int strStr(string haystack, string needle){int next[10007]={0}, nextval[10007]={0};getNext(next, needle);getNextval(nextval, next, needle);int i=-1, j=-1;//i是主串,j是模式串int flag=0;//记录是否匹配模式串while(1){if(j==-1||haystack[i]==needle[j]){i++;j++;}else{j=nextval[j];}if(j==needle.length())//匹配成功{flag=i-needle.length();return flag;}if(i==haystack.length())return -1;}}void getNext(int next[], string s){next[0]=-1;int i=0, j=-1;while(i<s.length()){if(j==-1||s[i]==s[j])//前面都匹配{i++;j++;next[i]=j;}else{j=next[j];}}}void getNextval(int nextval[], int next[], string s){nextval[0]=-1;for(int i=1; i<s.length(); i++){if(s[i]==s[next[i]])//该元素等于next里面的元素,因为字符串的首索引是0{nextval[i]=nextval[next[i]];}else{nextval[i]=next[i];}}}
};

可能大家还有一点疑惑:为什么我的下标是从-1开始,因为字符串的首字符下标是0,而书上的那些例题讲解都是用字符数组存储字符串,它的首字符下标是从1开始。

建议看懂理解了的同学去力扣重新做一下这道题,加深印象。希望能帮助到大家,欢迎指正!

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

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

相关文章

electron nsis 安装包 window下任务栏无法正常固定与取消固定 Pin to taskbar

问题 win10系统下&#xff0c;程序任务栏在固定后取消固定&#xff0c;展示的程序内容异常。 排查 1.通过论坛查询&#xff0c;应该是与app的api setAppUserModelId 相关 https://github.com/electron/electron/issues/3303 2.electron-builder脚本 electron-builder…

三、低代码平台-单据配置(单表增删改查)

一、业务效果图 主界面 二、配置过程简介 配置流程&#xff1a;业务表设计 -》业务对象建立-》业务单据配置-》菜单配置。 a、业务表设计 b、业务对象建立 c、业务单据配置 功能路径&#xff1a;低代码开发平台/业务开发配置/单据配置维护 d、菜单配置

GCN原理回顾论文导读

Cora_dataset description Cora数据集是一个常用的学术文献用网络数据集&#xff0c;用于研究学术文献分类和图网络分析等任务。 该数据集由机器学习领域的博士论文摘要组成&#xff0c;共计2708篇论文&#xff0c;涵盖了7个不同的学科领域。每篇论文都有一个唯一的ID&#xf…

李沐动手学习深度学习——3.5练习

减少batch_size&#xff08;如减少到1&#xff09;是否会影响读取性能&#xff1f; 肯定会影响&#xff0c;计算机io性能而言&#xff0c;随着batch_size增大&#xff0c;读取越来越快&#xff0c;需要的时间越少。这里会涉及到计算机操作系统的知识点&#xff0c;内存与硬盘之…

AmzTrends x TiDB Serverless:通过云原生改造实现全局成本降低 80%

本文介绍了厦门笛卡尔数据&#xff08;AmzTrends&#xff09;在面临数据存储挑战时&#xff0c;选择将其数据分析服务迁移到 TiDB Serverless 的思路和实践。通过全托管的数据库服务&#xff0c;AmzTrends 实现了全局成本降低 80% 的效果&#xff0c;同时也充分展示了 TiDB Ser…

kafka进阶(二)

文章目录 前言一、Ack机制二、ISR集合总结 前言 本篇主要介绍kafka 的 Ack机制 和 ISR集合 一、Ack机制 Kafka提供了三种不同的应答机制&#xff08;ACK&#xff09;&#xff1a; acks0&#xff1a;这是最不可靠的模式。在这种模式下&#xff0c;生产者不会等待来自服务器的…

三、软考-系统架构设计师笔记-计算机系统基础知识

计算机系统概述 计算机系统是指用于数据管理的计算机硬件、软件及网络组成的系统。 它是按人的要求接收和存储信息&#xff0c;自动进行数据处理和计算&#xff0c;并输出结果信息的机器系统。 冯诺依曼体系计算机结构&#xff1a; 1、计算机硬件组成 冯诺依曼计算机结构将…

正向代理的反爬虫与防DDoS攻击:保护网站免受恶意行为

目录 前言 一、正向代理的原理 二、正向代理的反爬虫功能 1. IP地址隐藏 2. 请求多样化 三、正向代理的防DDoS攻击功能 1. 均衡负载 2. IP过滤 结论 前言 在当前互联网环境下&#xff0c;网站常常受到各种恶意行为的侵袭&#xff0c;其中包括爬虫和DDoS攻击。这些行为…

#WEB前端(DIV、SPAN)

1.实验&#xff1a;DIV、SPAN 2.IDE&#xff1a;VSCODE 3.记录&#xff1a; 类? 4.代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdev…

数据库系统架构与DBMS功能探微:现代信息时代数据管理的关键

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

现代化数据架构升级:毫末智行自动驾驶如何应对年增20PB的数据规模挑战?-OceanBase案例

毫末智行是一家致力于自动驾驶的人工智能技术公司&#xff0c;其前身是长城汽车智能驾驶前瞻分部&#xff0c;以零事故、零拥堵、自由出行和高效物流为目标&#xff0c;助力合作伙伴重塑和全面升级整个社会的出行及物流方式。 在自动驾驶领域中&#xff0c;是什么原因让毫末智行…

Linux——基本指令

系列文章目录 文章目录 系列文章目录一、Linux基本常识二、Linux基本指令2.1 mkdir指令&#xff08;重要&#xff09;2.2 rmdir指令2.3 rm指令&#xff08;重要&#xff09;2.4 touch指令2.5 ls指令2.6 pwd指令2.7 cd指令2.7.1 Linux中的目录结构2.7.2 绝对路径和相对路径2.7.3…

对程序、进程、线程、并发、并行、高并发概念的讲解

一、概述 程序、进程、线程、并发、并行和高并发是计算机科学领域中非常重要的概念。 了解进程、线程、并发和并行的概念&#xff0c;可以更好地利用计算机的多核处理器和并行计算能力&#xff0c;提高计算机性能。 了解进程和线程为操作系统中的资源管理提供了基础&#xff…

【风格迁移】对比度保持连贯性损失 CCPL:解决图像局部失真、视频帧间的连贯性和闪烁

对比度保持连贯性损失 CCPL&#xff1a;解决图像局部失真、视频帧间的连贯性和闪烁 提出背景解法&#xff1a;对比度保持连贯性损失&#xff08;CCPL&#xff09; 局部一致性假设 对比学习机制 邻域调节策略 互信息最大化对比学习&#xff1a;在无需标签的情况下有效学习区分…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的教室人员检测与计数(Python+PySide6界面+训练代码)

摘要&#xff1a;开发教室人员检测与计数系统对于优化教学资源和提升教学效率具有重要意义。本篇博客详细介绍了如何利用深度学习构建此系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5的性能&#xff0c;展示…

[vue error] TypeError: AutoImportis not a function

问题详情 问题描述: element plus按需导入后&#xff0c;启动项目报错&#xff1a; 问题解决 将unplugin-auto-import 回退到0.16.1 npm install unplugin-auto-import0.16.1 安装完后再次运行就好了

差分题练习(区间更新)

一、差分的特点和原理 对于一个数组a[]&#xff0c;差分数组diff[]的定义是: 对差分数组做前缀和可以还原为原数组: 利用差分数组可以实现快速的区间修改&#xff0c;下面是将区间[l, r]都加上x的方法: diff[l] x; diff[r 1] - x;在修改完成后&#xff0c;需要做前缀和恢复…

PYTHON 自动化办公:压缩图片(PIL)

1、介绍 在办公还是学习过程中&#xff0c;难免会遇到上传照片的问题。然而照片的大小限制一直都是个问题&#xff0c;例如照片限制在200Kb之内&#xff0c;虽然有很多图像压缩技术可以实现&#xff0c;但从图像处理的专业来说&#xff0c;可以利用代码实现 这里使用的库函数是…

观成科技:加密C2框架Covenant流量分析

工具介绍 Covenant是一个基于.NET的开源C2服务器&#xff0c;可以通过HTTP/HTTPS 控制Covenant agent&#xff0c;从而实现对目标的远程控制。Covenant agent在与C2通信时&#xff0c;使用base64/AES加密载荷的HTTP隧道构建加密通道。亦可选择使用SSL/TLS标准加密协议&#xf…

Java网络通信TCP

目录 TCP两个核心类 服务端 1.用ServerSocker类创建对象并且手动指定端口号 2.accept阻塞连接服务端与客户端 3.给客户端提供处理业务方法 4.处理业务 整体代码 客户端 1.创建Socket对象&#xff0c;并连接服务端的ip与端口号 2.获取Socket流对象&#xff0c;写入数据…