6、C++算法之代码随想录(字符串)——实现strStr()(KMP)

(1)问题

        力扣——28. 找出字符串中第一个匹配项的下标 - 力扣(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 。
(2)思路

        第一种:使用两个for循环进行匹配。时间复杂度O(n^2)。

        第二种:使用KMP算法进行匹配。(本文使用这种方法)。

(3)KMP算法

        KMP算法是一种用于字符串匹配的高效算法。其核心思想是——利用已匹配的部分信息,通过一个部分匹配表(next数组),从而避免不必要的回溯。KMP算法的时间复杂度为O(n+m)。

        KMP算法的实现核心就是构造这个部分匹配表。其中涉及到找最大前后缀与存储。原理可以看代码随想录。

(4)解题思路

        1.将一些特殊情况排除,例如字符串为0的情况。

        2.创建一个容器用来当做next数组。

        3.创建next数组。

        4.遍历文本字符串,如果存在文本字符串与匹配字符串不相等的就回溯。

        5.如果相等,匹配字符串下标+1;

        6.如果匹配字符串到达最后,说明匹配成功,用文本字符串下标减去匹配字符串长度再加1。

    void getNext(int* next,const string& s)
    {
        //j前缀起点,i后缀起点  
        int j=0;
        next[0] = 0;
        for(int i=1;i<s.size();i++)
        {
            while(j>0&&s[i]!=s[j])
            {
                j=next[j-1];
            }
            if(s[i]==s[j])  j++;
            next[i] = j;
        }
    }

    int strStr(string haystack, string needle) {

        if(haystack.size()==0||needle.size()==0) return -1;

        vector<int> next(needle.size());

        getNext(&next[0],needle);

        for(int i=0,j=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-j+1;
        }
        return -1;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值