首页 > 其他分享 >代码随想录 字符串 test 6(KMP,超详细)

代码随想录 字符串 test 6(KMP,超详细)

时间:2025-01-18 13:29:39浏览次数:3  
标签:相等 匹配 int needle 随想录 next 后缀 KMP test

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

一 暴力:

        以主串中的每个字符为起点,每次匹配从当前主串的起点和子串的首位开始匹配:匹配成功:返回本次匹配的主串起点。匹配失败:以主串的下一个字符作为新起点,重新尝试匹配。时间复杂度为o(m*n)(m为主串长度,n为子串长度,因为每次从主串起点开始都要遍历一遍子串)

class Solution {
public:
    int strStr(string haystack, string needle) {
        for(int i = 0; i <= haystack.size() - needle.size(); i++){
            int j = i, k = 0;//j为每次主串的起点,k为子串的起点

            while(k < needle.size() && needle[k] == haystack[j]){
                j++, k++;
            }

            if(k == needle.size())
                return i;
        }
        
        return -1;
    }
};

二 KMP:

关键:通过预处理子串,记录模式串中每个位置的最长相同前缀和后缀的长度。当匹配失败时,利用这些信息跳过不必要的比较。算法分为两部分:next数组的建立以及模式串匹配的过程。

1 next数组:

        采用next数组从0开始,next数组值即当前位置子串的最长相等前后缀,如ababa,此时最后一个字符a处的最长相等前后缀为"aba",因此他的next数组值为3,同理倒数第二个字符b的next数组值为2,整体next数组为00123,因此如果当前位置j匹配失败(第1个位置特殊讨论),说明他前面的字符s[j-1]匹配成功,此时next[j-1]也就是匹配成功部分的最长相等前后缀大小,说明下次匹配可以直接从该前缀的下一个字符开始匹配,也就是从next[j-1]开始(大小等于序号加1)。

        创建:此时可以将前缀当作子串,后缀当作主串(无非就是匹配成功并不返回,而是赋值)设置前缀指针j和后缀指针i,起始位置next[0]=0,j从0开始,i从1开始。注意i指针始终向后移动,先判断是否相等,再为当前next[i]赋值。如果相等,说明前后缀扩大,将j后移,如果不相等,将不相等的情形视为不匹配的情况,要想知道当前位置的最大前后缀,即j位置失配时下一个要检查的位置next[j-1],若此时相等,相等前后缀大小为next[j-1],若不相等则一直递归(因为要找前后缀的值,而不是判断是否匹配成功),直到相等或j=0为止。最后在本次遍历结束前将j的值赋给next[i]。

2 匹配:

        与上述类似,设置主串指针i,子串指针j,相等时两指针同时后移,不等时j一直利用next数组回退,如果j遍历到子串结尾就说明匹配成功。

3 代码:

class Solution {
public:
    void getNext(int* next, const string& needle){
        int j=0;
        next[0] = 0;

        for(int i = 1; i < needle.size(); i++){
            while(j > 0 && needle[i] != needle[j]){
                j = next[j - 1];
            }

            if(needle[i] == needle[j]){
                j++;
            }

            next[i] = j;
        }
    }
    int strStr(string haystack, string needle) {
        if(haystack.size() == 0) return 0;

        int next[needle.size()];

        getNext(next, needle);

        int j = 0;

        for(int i = 0; i < haystack.size(); i++){
            while(j > 0 && needle[j] != haystack[i]){
                j = next[j - 1];
            }

            if(needle[j] == haystack[i]){
                j++;
            }
            
            if(j == needle.size()){
                return i - needle.size() + 1;
            }
        }

        return -1;
    }
};

标签:相等,匹配,int,needle,随想录,next,后缀,KMP,test
From: https://blog.csdn.net/m0_73941517/article/details/145213048

相关文章

  • AtCoder Regular Contest 058 [ARC058] F - Unhappy Hacking
    题意:有三种操作,在右边添加0/1或删除最右边的数(空字符串无操作)给出操作数\(N\),字符串\(s\),问有多少种方法经过\(N\)次操作后得到字符串\(S\)思路最开始在想三维dp,虽然发现了性质,但是没想到很好的用法重要性质:答案与字符串内容无关,仅与字符串长度有关定义\(f_{i,j}\)为操作\(i......
  • 探秘Shortest与Stagehand:开启高效测试与自动化新篇
    探秘Shortest与Stagehand:开启高效测试与自动化新篇在数字化浪潮的推动下,网页自动化工具如同繁星般涌现,为众多行业带来了效率的变革。在这些工具中,Shortest和Stagehand凭借其出色的表现,成为了众多开发者、测试人员以及相关从业者的焦点。虽然二者都基于Playwright构建,但在功......
  • 【代码随想录】刷题记录(105)-打家劫舍
    题目描述:你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况......
  • 【代码随想录】刷题记录(103)-整数拆分
    题目描述:给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k>=2 ),并使这些整数的乘积最大化。返回 你可以获得的最大乘积 。 示例1:输入:n=2输出:1解释:2=1+1,1×1=1。示例 2:输入:n=10输出:36解释:10=3+3+4,3× 3× 4=......
  • 代码随想录 字符串 test 3
    54.替换数字(第八期模拟笔试)        为了不使用额外的空间,采用双指针,通过用旧指针遍历原数组计算出数字个数,进而计算出新数组应有的大小,然后新指针指向新数组的最后,此时新,旧指针都位于两数组的末尾,同时从后往前遍历,遇到数组,新指针就需要写入number,遇到字母,就赋值旧数......
  • 基于若依框架进行TestNG接口自动化框架搭建(二)
    目录一.前言二.引入TestNg三.创建接口自动化目录结构三.引入okhttp3四.开始编写第一条接口用例一.前言    在上一章节跟着操作把代码成功运行起来,就可以跟着本章节进行接口自动化代码编写,接口自动化使用的测试框架是TestNG,大家跟着我的步骤一步步往下操......
  • KMP算法
    KMP算法kmp算法主要解决的问题就是字符串匹配,本篇文章节选自我的LeetCode字符串,在此单独记录一下kmp算法题1:字符串匹配寻找匹配子串,并返回起始索引classSolution:defstrStr(self,haystack:str,needle:str)->int:start=-1i=0......
  • pytest测试框架集成钉钉机器人、邮件,并实现持续集成部署
    要结合多系统并存的架构,使用YAML文件编写测试用例,并集成钉钉、邮件通知功能以及CI/CD流程,以下是完整的实现方案。整体功能架构多系统测试支持:使用YAML文件定义测试用例,支持多系统间的模块化、分层管理。测试框架根据YAML文件动态加载测试用例,支持灵活扩展。......
  • 代码随想录算法训练营第8天 | 344.反转字符串,541. 反转字符串II,替换数字
    一、刷题部分1.1题目名称原文链接:代码随想录题目链接:344.反转字符串-力扣(LeetCode)1.1.1题目描述编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组s的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用O(1)的额外空间解决......
  • 代码随想录算法训练营第四天 | 24. 两两交换链表中的节点、19. 删除链表的倒数第N个节
    9-24.两两交换链表中的节点给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例1:输入:head=[1,2,3,4]输出:[2,1,4,3]示例2:输入:head=[]输出:[]示例3:输入:head=[1]输出:[1] 提......