稀碎从零算法笔记Day12-LeetCode:找出字符串中第一个匹配项的下标

题型:字符串、字符串匹配算法

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

来源:LeetCode

题目描述

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

题目思路

两种思路:暴力开撕 或者 字符串匹配算法(比如KMP算法)

暴力:笔者这里开了一个新的字符串temp来存haystack的前n个字符(假设n是needle.length()-1),然后看看temp和needle是否相等:相等就return i,不相等就让 i 右移

字符串匹配算法(施工完毕!)

KMP算法:重点:算法实现构建Next数组

这里先说一下KMP算法中的next数组 :其存储的是【最长相等前后缀的长度】

手写起来还是很简单的,关键是代码实现。

我的思路:双指针 i 和 j :其中 i 指向后缀的最后一位,j 有两重含义:① j 是最长前缀的长度 ② j 指向前缀的最后一位

然后就是判断最长相等前后缀:

感觉讲起来会很费劲,模拟一下代码的制行过程可能更好理解

C++代码

暴力code:

注意index越界

cpp 复制代码
class Solution {
public:
    int strStr(string haystack, string needle) {
        // 暴力
        string temp;
        if(haystack.length()<needle.length())//被匹配串比匹配串短,-1
            return -1;
        else
            for(int i=0;i<=haystack.length()-needle.length();i++)
            {
                temp="";//空串

                for(int j=i;j<i+needle.length();j++)//一次循环次数应该是匹配串的长度-1
                {
                    temp.push_back(haystack[j]);
                }

                if(temp==needle)
                {
                    return i;
                }
            }
        return -1;
    }
};

KMP算法:

cpp 复制代码
class Solution {
public:
    int strStr(string haystack, string needle) {
    // KMP算法
    //重点:求模式串前缀表 构建next数组
    int lenH=haystack.length(),lenN=needle.length();//文本串的长度 模式串的长度
    int j=0;//j是①前缀的最后一位  ②最长相等前后缀的长度
    vector<int> next(lenN);//next数组,长度为
    next[0]=0;
    // 构建next数组
    for(int i=1;i<lenN;i++)//i是后缀的最后一位
    {

        while(j>0 && needle[j] != needle[i])
        {
            j=next[j-1];//前后缀不相等,j就移动到i的前一位的next处
        }
        if(needle[i]==needle[j])
        {
            j++;
        }
        next[i]=j;//因为j是最长相等前后缀的长度
    }
    for(int i=0,j=0;i<lenH;i++)
    {
        while(haystack[i] != needle[j] && j>0)
        {
            j=next[j-1];
        }
        if(haystack[i] == needle[j])
            j++;
        if(j==lenN)//遍历完了模式串,表示haystack中有needle
            return i-lenN+1;
    }
    return -1;
    }
};

结算页面

相关推荐
ACP广源盛139246256734 小时前
Type-C 扩展坞方案选型笔记:DP1.4 转 HDMI2.0 桥接方案评估@ACP
笔记·硬件架构·hdmi·国产芯片·扩展坞
徐小夕4 小时前
花了3个月,我们做了一款 AI 版的“飞书文档”
前端·算法·github
Robert--cao4 小时前
移动底盘与机械臂联合规划:开源算法与工程实现
算法
小豆庄5 小时前
Mac 上给视频人脸打码:本地工具的依赖、追踪与推理管线
算法·视觉检测·视频·敏捷流程·纹理贴图
星夜离尘566 小时前
MATLAB 工程实验:从相邻块均值手写重叠 Allan 偏差,数清有效项
算法·matlab·均值算法
ss2737 小时前
AI时代首先数据库-PostgreSQL实战笔记 | 22 PostgreSQL实例与集群
数据库·笔记·postgresql
ss2737 小时前
AI时代首先数据库-PostgreSQL实战笔记 | 21 PostgreSQL进程与内存架构介绍
数据库·笔记·postgresql
y1su8 小时前
Leetcode 字符串模板
java·数据结构·算法·leetcode·职场和发展·动态规划
residual_fan8 小时前
船用柴油机动态机动工况故障诊断:控制感知仿射网络(CAAN)的技术实现
人工智能·算法·数据挖掘·数据分析
其实防守也摸鱼9 小时前
Cylab在线靶场——CTF中的通用技能
linux·数据库·学习·算法·靶场·ctf·学习网络安全