KMP算法笔记

kmp算法:(还是没理解太懂,但是差不多)
例子:aabaaf
           010120
i代表后缀末尾j代表前缀末尾和j++是最大回文串的长度(str[j++]之前的都相同)

例如:str=aab,最大回文串长度1,前缀aa,后缀ab时,str[1]之前的都相同,从str【1】开始比较,及a和b比较(描述的不好,下次看也不知道还能不能看懂)

例如:aabaaf,看 i 指向 f 时,看aabaa的最大回文串长度(此时 j =1, j++=2),下标2指向b与f比较
i从1开始一直循环size()-1次
一次循环需要和前后缀不同的情况,考虑前后缀相同的情况(得到next数组的值)

void getNext(int* next, const string& s) {
        int j = 0;
        next[0] = 0;
        for(int i = 1; i < s.size(); i++) {
            // 前后缀不相同了
            while (j > 0 && s[i] != s[j]) { // j要保证大于0,因为下面有取j-1作为数组下标的操作
                j = next[j - 1]; // 注意这里,是要找前一位的对应的回退位置了
            }
            if (s[i] == s[j]) {// 找到相同的前后缀
                j++;
            }
            next[i] = j;
        }
    }

求next数组的过程,相当于用整体的匹配规则(自己用自己的next数组)匹配前缀和后缀。上面代码的回退j=next[j-1]和整体匹配的时候 j 回到对应的next数组的位置操作一样。

整体匹配如下:

int strStr(string haystack, string needle) {
        if (needle.size() == 0) {
            return 0;
        }
        vector<int> next(needle.size());
        getNext(&next[0], needle);
        int j = 0;
        for (int i = 0; i < haystack.size(); i++) {
            while(j > 0 && haystack[i] != needle[j]) {//与求next数组逻辑相同
                j = next[j - 1];
            }
            if (haystack[i] == needle[j]) {
                j++;
            }
            if (j == needle.size() ) {
                return (i - needle.size() + 1);
            }
        }
        return -1;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值