28. 找出字符串中第一个匹配项的下标(力扣LeetCode)

文章目录

  • 28. 找出字符串中第一个匹配项的下标
    • 题目描述
    • 暴力
    • KMP算法

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

题目描述

给你两个字符串 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 <= 104
  • haystack 和 needle 仅由小写英文字符组成

暴力

// 定义Solution类
class Solution {
public:// strStr函数接受两个字符串参数:haystack(主字符串)和needle(子串)int strStr(string haystack, string needle) {// 初始化count变量来跟踪匹配的连续字符数int count=0;// 初始化k变量来跟踪needle字符串中的当前位置int k=0;// 遍历haystack字符串for(int i=0; i<haystack.size(); i++){// 如果当前字符匹配,增加count并移动到needle的下一个字符if(haystack[i] == needle[k]){count++;k++;// 打印出当前的匹配长度(主要用于调试)cout << count << endl;// 如果全部字符都匹配,返回第一个匹配字符的下标if(count == needle.size())return i - count + 1;}// 如果当前字符不匹配else{// 重置i为上一个匹配序列的开始的下一个位置i = i - count;// 重置count和k为0,重新开始匹配count = 0;k = 0;}}// 如果遍历了整个haystack都没有找到完全匹配的needle,返回-1return -1;}
};

重要的代码段解释:

  • int i=0; i<haystack.size(); i++: 这个循环遍历主字符串haystack。
  • if(haystack[i] == needle[k]): 检查当前haystack的字符是否与needle的当前字符匹配。
  • count++; k++;: 如果匹配,增加count(匹配的字符数)并且k增加,使得下一次循环检查needle的下一个字符。
  • if(count == needle.size()): 如果count等于needle的长度,说明已经找到一个完全的匹配,返回第一个匹配的下标。
  • else分支: 当一个不匹配发生时,代码会重置i到当前检查序列的开始的下一个字符,并重置count和k为0,意味着重新开始匹配。
    需要注意的是,这段代码的性能并不是最优的,因为在发现一个字符不匹配时,它会回溯到上一个匹配序列的开始后面一个字符重新开始匹配,可能会导致多次重复检查同一个字符。更高效的字符串匹配算法如KMP算法能够在不回溯主字符串的情况下继续匹配。

KMP算法

不懂KMP算法的看这篇文章:28. 实现 strStr()

构造next数组图解
在这里插入图片描述

// 定义解决方案类
class Solution {
public:// strStr成员函数,接受两个字符串:haystack(搜索范围)和needle(目标字符串)int strStr(string haystack, string needle) {// 定义一个数组next用于存储KMP算法中的部分匹配表int next[needle.size()];// 计算needle的部分匹配表getnext(next, needle);//得到next数组// 定义一个指针j,用于指向needle的当前匹配位置//这里的i和j理解和下面getnext函数中类似//因为要回退的是j,所以j对应的是needle//所以i对应haystackint j=0;// 遍历haystack字符串for(int i=0; i<haystack.size(); i++) {// 使用while循环处理不匹配的情况// 如果j大于0且当前字符不匹配,则回退j到部分匹配的位置while(j > 0 && haystack[i] != needle[j]) {j=next[j-1];}// 如果当前字符匹配,则指针j递增if(haystack[i] == needle[j]) {j++;}// 如果j的值等于needle的长度,则表明找到了完整匹配// 返回匹配的起始下标if(j == needle.size()) {return i - needle.size() + 1;}}// 如果没有找到匹配,返回-1return -1;}private:// getnext函数用于计算KMP算法中的部分匹配表void getnext(int *next, const string& s) {// 初始化j为0,j指向前缀的末尾位置int j=0;// next数组的第一个元素总是0next[0]=0;//0的位置也是回退到0// 使用for循环计算next数组的其余部分for(int i=1; i<s.size(); i++) {//要比较前后缀是否相等,i从1开始,且i最后指向后缀末尾位置(s.size()-1)// 如果前后缀不相同,回退j的位置while(j > 0 && s[i] != s[j]) {j=next[j-1];//j进行回退}// 如果前后缀相同,j递增if(s[i] == s[j]) {j++;}// 更新next数组//更新分两种情况://第一种:相等时就更新//第二种:不相等时,j回退到0时更新为0next[i] = j;}}
};

这段代码中的KMP算法包含两个主要部分:

  1. getnext()函数计算部分匹配表(也就是next数组)。部分匹配表是KMP算法的核心,它记录了模式字符串needle中的前后缀的最长公共元素的长度。在搜索过程中不匹配时,可以利用这个信息跳过一些不必要的比较。

  2. strStr()函数使用部分匹配表来加速搜索过程。当出现不匹配的情况时,不用像暴力搜索那样从头开始比较,而是根据next数组回退到某一位置继续比较。

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

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

相关文章

mapbox高德地图与相机

mapbox高德地图与相机 本案例使用Mapbox GL JavaScript库创建高德地图。 演示效果引入 CDN 链接地图显示 创建地图实例定义地图数据源配置地图图层 设置地图样式实现代码 1. 演示效果 2. 引入 CDN 链接 <script src"https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapb…

项目实战:Qt监测操作系统cpu温度v1.1.0(支持windows、linux、国产麒麟系统)

若该文为原创文章&#xff0c;转载请注明出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/136277231 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结…

全面升级!Apache HugeGraph 1.2.0版本发布

图数据库以独特的数据管理和分析能力&#xff0c;在企业数智化转型的过程中正在成为数据治理的核心&#xff0c;根据IDC调研显示&#xff0c;95%的企业认为图数据库是重要的数据管理工具&#xff0c;超过65%的厂商认为在业务上图数据库优于其他选择&#xff0c;尤其是在金融风控…

Unity零基础到进阶 | Unity中的 RectTransformUtility 方法整理汇总

Unity零基础到进阶 ☀️| RectTransformUtility 方法整理汇总一、RectTransformUtility 官方文档1.1 RectTransformUtility.CalculateRelativeRectTransformBounds&#xff08;重&#xff09;1.2 RectTransformUtility.FlipLayoutAxes1.3 RectTransformUtility.FlipLayoutOnAxi…

观察者模式与发布订阅模式

观察者模式 定义&#xff1a; 观察者模式是一种行为型设计模式&#xff0c;定义对象间的一种一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都得到通知并被自动更新。 结构图&#xff1a; ES6简易代码实现&#xff1a; //ts环境下…

Nginx——安装和反向代理

Nginx安装与应用 1.1 Nginx介绍 Nginx 是一个高性能的HTTP和反向代理服务器,特点是占有内存少&#xff0c;并发能力强 Nginx可以作为静态页面的web服务器&#xff0c;同时还支持CGI协议的动态语言&#xff0c;比如perl、php等。但是不支持java。Java程序只能通过与tomcat配合…

谷歌AI发展史:从阿尔法围棋到Gemini与Gemma的开源创新

谷歌一直是人工智能领域的重要推动者。本文将回顾谷歌AI的发展历程&#xff0c;从阿尔法围棋到现如今的Gemini和Gemma&#xff0c;探讨谷歌在人工智能领域的重大突破和创新。 1. 引言 在计算机科学领域&#xff0c;谷歌一直是人工智能&#xff08;AI&#xff0…

MasterAlign全景视觉点胶应用软件说明书

MasterAlign视觉软件通过高精度的图像处理和机器学习算法&#xff0c;实现了对点胶过程的全面控制和管理。以下是关于MasterAlign在全景视觉点胶应用场景中如何使用的详细说明。看完全文相信一定能让您快速上手使用。

多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型

多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型 目录 多维时序 | Matlab实现CPO-BiTCN-BiGRU冠豪猪优化时间卷积神经网络双向门控循环单元多变量时间序列预测模型预测效果基本介绍程序设计参考资料 预测效果 基本介绍…

基于R语言的Meta分析【全流程、不确定性分析】方法与Meta机器学习技术应用

Meta分析是针对某一科研问题&#xff0c;根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法&#xff0c;对来源不同的研究成果进行收集、合并及定量统计分析的方法&#xff0c;最早出现于“循证医学”&#xff0c;现已广泛应用于农林生态&#xff0c;资源环境等方面。…

设计模式(六)代理模式

相关文章设计模式系列 1.代理模式简介 代理模式介绍 代理模式也叫委托模式&#xff0c;是结构型设计模式的一种。在现实生活中我们用到类似代理模式的场景有很多&#xff0c;比如代购、代理上网、打官司等。 定义 为其他对象提供一种代理以控制这个对象的访问。 代理模式…

Layer1 明星项目 Partisia Blockchain 何以打造互操作、可创新的数字经济网络

我们的目标是创建一个以用户为中心的全新数字经济网络&#xff1a;在去信任化和公平透明的环境下&#xff0c;所有的隐私数据都能够得到天然保障&#xff0c;企业、用户等各角色的协作与共享将会更顺利地进行。 —— Partisia Blockchain 团队 作为一个以 Web3 安全为技术方向的…

Linux学习之vi/vim详细介绍

目录 ​编辑 1. 什么是 vim&#xff1f; 2. vi/vim 的使用 2.1 命令模式 2.2 输入模式 2.3 底线命令模式 3. vi/vim 使用实例 3.1 使用 vi/vim 进入一般模式 3.2 按下 i 进入输入模式(也称为编辑模式)&#xff0c;开始编辑文字 3.3 按下 ESC 按钮回到一般模式…

jenkins+kubernetes+git+dockerhub构建devops云平台

Devops简介 k8s助力Devops在企业落地实践 传统方式部署项目为什么发布慢&#xff0c;效率低&#xff1f; 上线一个功能&#xff0c;有多少时间被浪费了&#xff1f; 如何解决发布慢&#xff0c;效率低的问题呢&#xff1f; 什么是Devops&#xff1f; 敏捷开发 提高开发效率&…

CKA认证,开启您的云原生之旅!

在当今数字化时代&#xff0c;云计算已经成为企业和个人发展的关键技术。而获得CKA&#xff08;Certified Kubernetes Administrator&#xff09;认证&#xff0c;将是您在云原生领域迈出的重要一步。 CKA认证是由Kubernetes官方推出的权威认证&#xff0c;它旨在验证您在Kuber…

vue:实现顶部消息横向滚动通知

前言 系统顶部展示一个横向滚动的消息通知&#xff0c;就是消息内容从右往左一直滚动。 效果如下&#xff1a; 代码 使用 <template><div class"notic-bar"><img :src"notic" class"notice-img" /><div class"noti…

C++之类和对象(2)

目录 1.类的6个默认成员函数 2. 构造函数 2.1 概念 2.2 特性 3.析构函数 3.1 概念 3.2 特性 4. 拷贝构造函数 4.1 概念 4.2 特征 5.赋值运算符重载 5.1 运算符重载 5.2 赋值运算符重载 2. 赋值运算符只能重载成类的成员函数不能重载成全局函数 3. 用户没有显式实现时&…

【Flink CDC(一)】实现mysql整表与增量读取

文章目录 一. 运行前准备1. 依赖1.1. Maven dependency1.2. SQL Client JAR&#xff08;推荐&#xff09; 2. 配置 MySQL 服务器&#xff08;必须&#xff09; 二. 功能说明1. 启动模式2. 全量阶段支持 checkpoint3. 关于无主键表Exactly-Once 处理 三. 实战1. 实现mysql整表与…

如何用生成式AI创建食谱,解决五岁孩童挑食问题?

如何处理孩子挑食问题&#xff0c;对父母来说可能是一个挑战。这需要耐心、创造力和策略的结合。在深入具体策略之前&#xff0c;了解五岁儿童的口味偏好仍在发展中&#xff0c;他们的饮食行为受多种因素影响&#xff0c;包括气质、接触不同类型食物的程度以及父母对饮食的态度…

【ArcGIS】利用DEM进行水文分析:流向/流量等

利用DEM进行水文分析 ArcGIS实例参考 水文分析通过建立地表水文模型&#xff0c;研究与地表水流相关的各种自然现象&#xff0c;在城市和区域规划、农业及森林、交通道路等许多领域具有广泛的应用。 ArcGIS实例 某流域30m分辨率DEM如下&#xff1a; &#xff08;1&#xff09…