28. 实现 strStr()

news/2025/2/26 21:43:44/文章来源:https://www.cnblogs.com/gqzz/p/18739770

从文本串haystack中找到一个与模式串needle相匹配的子串,常规的暴力求解时间消耗很大,目前最常用的就是KMP算法。
KMP算法的核心思想就是利用前缀和后缀相同的部分,也就是最长公共前后缀来帮助匹配。具体的思路这两个回答讲的很好。
https://www.zhihu.com/question/21923021/answer/281346746
https://www.zhihu.com/question/21923021/answer/37475572
先看了这两个回答再来看下面的部分
当在某一处失配时,该处以前的模式串部分和文本串一定是相同的,然后这相同的一部分中,它的前缀和后缀又有相同的部分,这个时候,可以将模式串中相同那个前缀来对应文本串中的那个后缀,这样就能够不会退文本串当前的位置,而只是更新模式串用来与文本串进行匹配的字符。要是还失配,则重复这一步骤,寻找次大的公共前缀后缀串,而这个次大串其实也就是当前公共前缀后缀串的最大公共前缀后缀串。
对于这一部分来说,就是让模式串的前缀作为模式串,模式串自己作为文本串进行匹配,来求next数组。next数组是KMP算法的核心,它记录了模式串的每个位置的最长公共前后缀长度。这个数组用于在匹配失败时快速跳过不必要的比较。
具体代码:

class Solution {
public://求next数组void getNext(int* next, const string& s) {int j = 0;		//j表示的是当前这个字符之前已经匹配的前缀长度,也就等于当前字符之前的公共前后缀长;//同时也代表了当前模式串进行匹配的位置next[0] = 0;	//next[i]的值表示模式串中从0到i的子串的最长公共前后缀的长度,一个字符的串没有前缀,因此为0for(int i = 1; i < s.size(); i++) { while (j > 0 && s[i] != s[j]) {//不匹配时回退到次大的公共前后缀重新匹配,直到回退到j=0,这时候就相当于重新开始从模式串头匹配j = next[j - 1]; //next[i] = j;}if (s[i] == s[j]) {//新匹配上了一个字符,公共前后缀长+1j++;//next[i]=j;}next[i] = j;}}int strStr(string haystack, string needle) {if (needle.size() == 0) {return 0;}vector<int> next(needle.size());getNext(&next[0], needle);int j = 0;for (int i = 0; i < haystack.size(); i++) {while(j > 0 && haystack[i] != needle[j]) {j = next[j - 1];}if (haystack[i] == needle[j]) {j++;}if (j == needle.size() ) {return (i - needle.size() + 1);}}return -1;}
};

举例:
假设模式串needle = "abababc",我们逐步计算next数组:
i = 0:
next[0] = 0(单个字符没有前缀和后缀)。

i = 1:
s[1] = 'b',j = 0。
s[1] != s[0],j保持为0。
next[1] = 0。

i = 2:
s[2] = 'a',j = 0。
s[2] == s[0],j++变为1。
next[2] = 1。

i = 3:
s[3] = 'b',j = 1。
s[3] == s[1],j++变为2。
next[3] = 2。

i = 4:
s[4] = 'a',j = 2。
s[4] == s[2],j++变为3。
next[4] = 3。

i = 5:
s[5] = 'b',j = 3。
s[5] == s[3],j++变为4。
next[5] = 4。

i = 6:
s[6] = 'c',j = 4。
s[6] != s[4],j = next[3] = 2。
s[6] != s[2],j = next[1] = 0。
s[6] != s[0],j保持为0。
next[6] = 0。
最终,next数组为:[0, 0, 1, 2, 3, 4, 0]。

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

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

相关文章

C#/.NET/.NET Core技术前沿周刊 | 第 27 期(2025年2.17-2.23)

前言 C#/.NET/.NET Core技术前沿周刊,你的每周技术指南针!记录、追踪C#/.NET/.NET Core领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿,助力技术成长与视野拓宽。欢迎投稿、推荐或自荐优质文章、项目、学习资源等…

Jenkins详解教程

1.介绍2.Jenkins CI/CD 流程3.部署Jenkins查看初始密码4 使用Jenkins

Redis概述安装与基本数据类型

Redis概述安装与基本数据类型 1. 什么是NoSQL NoSQL( Not Only SQL ),意即不仅仅是SQL, 泛指非关系型的数据库。Nosql这个技术门类,早期就有人提出,发展至2009年趋势越发高涨。 2. NoSQL的广泛应用 随着大数据的兴起,数据量的暴增,数据类型的丰富,传统的关系数据库在应付动…

Hello! I am Zhan Yijue,nice to meet you

这个作业属于哪个课程 23软件工程这个作业要求在哪里 【作业1】自我介绍+软工5问这个作业的目标 学习使用 Markdown, 熟练掌握 GitHub 及 Git 的使用方法, 建立个人博客个人介绍 ❤️ 兴趣爱好听歌 🎧 书法📝 看书,尤其是科幻小说 📊 二次元爱好者 🎩📖 学习经历广东…

Hugging Face 发布 Python WebRTC 库:构建实时音视频应用;微软 Magma:多模态跨数字物理世界丨日报

开发者朋友们大家好:这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 技术 」、「有亮点的 产品 」、「有思考的 文章 」、「有态度的 观点 」、「有看点的 活动 」,但内容仅代表编辑…

1Panel 专业版评测:全面超越宝塔的运维面板新标杆

一、 UX体验与移动端适配:更直观的跨平台交互 1Panel 专业版在用户体验上实现了对宝塔的全面超越。其界面采用现代化设计语言,以黑金主题 为代表的可定制化主题系统支持一键切换,视觉风格更符合技术审美,同时保持功能模块的清晰布局。相较于宝塔复杂的多级菜单,1Panel 的 …

基于抖音agent平台Cozi打造Agent智能体

AI Agent 一、AI Agent(智能体)与开发平台 【1】AI Agent的概念 AI Agent直接翻译更准确,AI代理人。AI Agent是指可以自主执行任务或目标的系统,它可以是一个软件,也可以是一个智能机器,这些系统通过感知环境并在此基础上做出决策。AI Agent可以集成多种技术,包括AI大模…

纯离线部署本地知识库LLM大模型

纯离线部署本地知识库LLM大模型 一、下载离线大模型下载的网址:https://hf-mirror.com/deepseek qwen 相关的模型,只建议使用1.5B的,GGUF后缀的模型 推荐下载llama相关模型,同样是GGUF后缀的,自己笔记本电脑推荐下载8B的 二、下载大模型管理平台 LM Studio下载网址:https…

mailto链接

本文主要内容转载自Haorooms!好用的mailto网站话不多说直接上正菜! 大佬dawsbot提供的工具mailto.vercel.app前言 今天看到老外写的一篇关于mailto: HTML e-mail 的文章,感觉很新奇,以前从来没有这么用过,用email的时候,最多用过mailto,但是其中穿链接参数,还是第一次看…

二次开发(第一周作业)

(1) 来源 C++ 大作业 超市收银系统 - shugen - 博客园 该文章介绍了一个软件的实现过程,并提供了相关代码。通过对该软件的分析对其进行了改进和二次开发。 (2) 运行环境+运行结果的截图(伸缩代码附上) 操作系统:Windows 11 开发工具:Dev-c++ 编程语言:C++ 运行结果截…

iconfont本地引入

本地引入iconfont的好处 Butterfly主题自带的Font Awesome图标库免费版里有好多图标没有,而阿里巴巴的开源图标iconfont里的图标非常丰富,所以可以同时引入一下iconfont图标作为Font Awesome图标库的补充。 考虑到在线引入的icon图标大小都是16x16的,而Font Awesome图标一般…