【拓展KMP算法】知识点讲解+模板

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38033475/article/details/80284568




void getnext() {
    next[1] = n;
    int p = 1;
    while(p < n && t[p] == t[p + 1]) p++;
    next[2] = p-1;        //对本身的比较来说,先可以把next[1]和next[2]都赋好(求next[2]相当于把字符串向右移一位来比)
    int k = 2,l;
    for(int i = 3; i <= n; i++) {
        p = k + next[k] - 1;
        l = next[i - k + 1];
        if (i + l <= p) next[i] = l;
        else {
            int j = p - i + 1;
            if(j < 0)     j = 0;
            while(i + j <= n && t[i + j] == t[j + 1])     j++;
            next[i] = j;
            k = i;
        }
    }
}



注意:t是匹配前面的,s是匹配后面的。n是t的长度,m是s的长度 

void getextend() {
    int p = 0;
    while (p < m && p < n && s[p + 1] == t[p + 1]) {
        p++;
    }
    extend[1] = p;
    int k = 1, l;
    for (int i = 2; i <= m; i++) {
        p = k + extend[k] - 1;
        l = next[i - k + 1];
        if (i + l <= p) {
            extend[i] = l;
        } else {
            int j = p - i + 1;
            if(j < 0) j = 0;
            while(i + j <= m && j + 1 <=n && s[i + j] == t[j + 1])    j ++;
            extend[i] = j;
            k = i;
        }
    }
}


如何记忆

是就是把上面第一张图(红蓝颜色)的两张记住,然后明白概念“next[i]的意思是截取i下标之后的子数组,与原数组从开头开始比较,有多少重复元素——尾巴和脑壳比相同的长度”。如此思考,将求next[i]转化为求next[i-k+1]。

然后之后要注意得到的这个长度和p-i+1进行比较。如果>了要再往后比较加j。


注意使用的输入

这里的下标都默认是从1开始的,但一般来说我们输入都是字符数组直接获取存储,怎么从下标1开始存储以及怎么求实际输入字符串的长度呢?

这里要记住(不然你不能直接搭配以上模板用啊~):

gets(t+1);   //输入,从字符数组t的下标1开始存储
n=strlen(t+1);  //strlen是字符数组求实际长度的函数,传参t+1表示从t[1]开始计算长度!很实用呀有没有!!!


阅读更多
换一批

没有更多推荐了,返回首页