Leetcode 28 实现strStr()

题目描述

题解1(find)

class Solution {
public:
    int strStr(string haystack, string needle) {
        return haystack.find(needle);
    }
};

提交结果

题解2(KMP)

class Solution {
private:
    vector<int> nextj;
    void getnext(string s){
        nextj.resize(s.size());
        int j=-1;
        nextj[0]=j;
        for(int i = 1; i < s.size(); i++)//注意i从1开始
        {
            while(j >= 0 && s[i] != s[j+1])//处理前后缀不相同的情况
            {
                j = nextj[j];//向前回溯
            }
            if(s[i] == s[j+1])//找到相同的前后缀
            {
                j++;
            }
            nextj[i] = j;//将j(前缀的长度)赋给next[i]
        }
    }    
public:
    int strStr(string haystack, string needle) {
        if(!needle.size()) return 0;
        if(! haystack.size()) return -1; 
        getnext(needle);
        int i = 0, j = -1;
        while(i < haystack.size()){
            while(j >= 0 && haystack[i]!=needle[j+1])//不匹配
            {
                j = nextj[j];//j寻找之前的位置
            }
            if(haystack[i]==needle[j+1])//匹配
            {
                j++;//j和i同时向后移动
            }
            if(j == (needle.size()-1))//文本串s里出现了模式串t
            {
                return (i-needle.size()+1);//返回其位置
            }
            i++;
        }
        return -1;
        
    }
};

提交结果

题解3(Sunday:参考)

class Solution {
public:
    int strStr(string haystack, string needle) {
        if(!needle.size()) return 0;
        if(! haystack.size()) return -1; 

        int slen=haystack.size();
        int tlen=needle.size();
        int i=0,j=0;//i指向源串首位 j指向子串首位
        int k;
        int m=tlen;//第一次匹配时 源串中参与匹配的元素的下一位
        
        while(i < slen)
        {
            if(haystack[i]!=needle[j])
            {
                for(k=tlen-1;k>=0;k--)//遍历查找此时子串与源串[i+tlen+1]相等的最右位置
                {
                    if(needle[k]==haystack[m])
                        break;
                }
                i=m-k;//i为下一次匹配 源串首位(step) Sunday算法核心:最大限度跳过相同元素
                j=0;//j依然为子串首位
                m=i+tlen;//m为下一次参与匹配的源串最后一位元素的下一位
                if(m>slen)//当下一次参与匹配的源串字数的最后一位的下一位超过源串长度时
                    return -1;
            }
            else
            {
                if(j==tlen-1)//若j为子串末位 匹配成功 返回源串此时匹配首位
                    return i-j;
                i++;
                j++;
            }
        }
        return -1;//当超过源串长度时 
    }
};

提交结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值