LeetCode-28.实现strStr()

28.实现strStr()

今天看了串,主要是学习KMP算法,所以在力扣上找了一个模式匹配的题,虽然这个题用暴力,用一句调用(!!!)就可以过,但是主要是为了练一下KMP啦

  • 题目描述

实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
28.实现strStr()

  • 分析KMP

KMP真的很难记,理解起来也很麻烦
浅浅描述一下:
模式匹配就是在主串中寻找子串(也就是模式)出现的位置。
我们用i指针指向主串,用j指针指向模式。

暴力匹配 就是,首先让i,j都指向字符串中第一个位置(从1开始编号),即i = 1 , j = 1;
若该字符匹配成功,则i++、j++继续匹配,直至完全匹配。
若匹配失败,则i回退到i - j + 1,j回退到1,重新开始匹配。
//
KMP算法 中,i不需要回退
而是当匹配失败时,使j指向 next[ j ] 的位置,再使i,j进行匹配。
//
next[j] 是啥捏?
next[j] = k , k 是使得模式中’1…k-1’位置的子串与’j-k+1…j-1’位置的子串相等的位置
k满足 1<k<j , 且不存在 k’ > k满足上式
//
next[j] 怎样计算捏?
下面是一个类似于数学归纳法的推理(手动狗头)
//*******************************************************//
1.由定义我们知 next[1] = 0
2.设 next[j] = k , 则有 模式中’1…k-1’位置的子串与’j-k+1…j-1’位置的子串相等
3.求next[j+1]
(1)若k位置的字符与j位置的字符相等,则有 模式中’1…k’位置的子串与’j-k+1…j’位置的子串相等
即有 next[j+1] = k+1 => next[j+1] = next[j] + 1
(2)若k位置的字符与j位置的字符不相等,则此时可以把问题转化为模式匹配的问题(我也很无语,我也很绕,我的脑袋也不够用)
整个模式串即是主串,又是模式串
k = next[k]
在实现中,为避免j位置的字符与next[j]的字符相同而是我们的移动没有意义,还要加上一个判断条件
//
友友们我找到了一个讲的很好的博主,可以看一下,超级清晰
顶呱呱的博主

  • 代码
    呜呜终于到代码部分了
class Solution {
public:
    int strStr(string haystack, string needle) {
        int i = 0 ; 
        int j = 0 ;
        int *next = get_next(needle);
        if(needle.empty())
            return 0;
        int hl = haystack.length();
        int nl = needle.length();
        while(i < hl && j < nl){
            if(j == -1 || haystack[i] == needle[j]){
                i++;j++;
            }
            else{
                j = next[j];
            }
        }
        if(j == needle.length()){
            return i - j;
        }
        else
            return -1;
        
    }
    int *get_next(string needle){
        int j = 0;
        int k = -1;
        int next[10005] = {0};
        next[0] = -1;
        while(j < needle.length() - 1){
            if(k == -1 || needle[j] == needle[k]){
                j++;k++;
                if(needle[j] == needle[k]){
                    //即j位置的字符与next[j]的字符相同
                    next[j] = next[k];//跳过
                }
                else{
                    next[j] = k;    
                }
                
            }
            else{
                k = next[k];
            }
        }
        return next;
    }
};

真的是太难了呜呜呜

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值