LeetCode 28.实现strStr()

主页有其他数据结构内容(持续更新中)

难度:Easy

代码:

class Solution {
public:
    //  构造next数组
    void getNext(int* next, const string& s) {
        int j = 0;
        next[0] = 0;    //  0号位置出错只能回到0号
        for(int i = 1; i < s.size(); i++) {
            //  j是左指针,i是右指针
            while (j > 0 && s[i] != s[j]) {
                //  j>0才能进入该循环,否则会出现数组下标非法的情况
                //  j-1是因为j位置已经不匹配了,而j-1是最后一个匹配的位置
                j = next[j - 1];
            }
            if (s[i] == s[j]) {
                j++;
                //  i++在循环结束自动做
            }
            next[i] = j;	
            //	但实际上由于向前看的规则,next数组的最后一位元素在匹配过程中永远不会被用到
            //	即使是模式串最后一个元素匹配出错,跳转目标也是next[s.size - 1 - 1]
        }
        //  对传统next数组进行优化
        //	由于next[s.size - 1]不会被调用,所以优化过程中也不会涉及到最后一位元素
        int nextval[s.size()];
        nextval[0] = 0;
        for (int k = 1; k < s.size(); ++k) {
            if (s[next[k - 1]] == s[k]){
            	//	如果即将跳转的目标下标所对应的字符和当前字符相同,就会出现无效跳转
            	//	优化的目的是确保不出现无效跳转
                if (next[k - 1] == 0){
                	//	如果当前跳转的目标下标已经为0,则无需再向前看,防止出现数组下标非法
                    nextval[k - 1] = next[next[k - 1]];
                }
                else{
                    nextval[k - 1] = next[next[k - 1] - 1];
                }
            }
            else{
            	//	若不存在无效跳转则保持不变,直接对应即可
                nextval[k - 1] = next[k - 1];
            }
        }
        //	将nextval数组复制给next数组
        for (int p = 0; p < s.size(); ++p) {
            next[p] = nextval[p];
        }
    }

    //  KMP字符串匹配
    int strStr(string haystack, string needle) {
        if (needle.size() == 0) {
            //  如果模式串为空串就返回0
            return 0;
        }
        int next[needle.size()];
        //  构造next数组
        getNext(next, needle);
        int j = 0;
        for (int i = 0; i < haystack.size(); i++) {
            //  双指针,i是原字符串的指针,j是模式串的指针
            while(j > 0 && haystack[i] != needle[j]) {
                //  j>0才能进入该循环
                //  j-1是因为j位置已经不匹配了,而j-1是最后一个匹配的位置
                j = next[j - 1];
            }
            if (haystack[i] == needle[j]) {
                j++;
            }
            if (j == needle.size() ) {
                //  已经匹配成功,最后一次的j++会让j移到下标为needle.size()的位置
                return (i - needle.size() + 1);
            }
        }
        //  未发现匹配的字符串就返回-1
        return -1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值