zoukankan      html  css  js  c++  java
  • KMP算法

    整体来看,KMP算法,在s中寻找p(p,pattern,s可能的子串)采用的思想是:
    1.预处理p,生成next数组;
    2.遍历中s的index不回溯,不匹配时下一个字符匹配p的next[j]字符,问题的复杂度由O(mn)下降到O(m+n)。;
    3.next数组有自动状态机的思想在里面;
    4.next数组其实是前缀数组的最前面和最后面共同的字符数。next数组有从-1开始的,有从0开始的。算法导论从0开始,但数组下标从1开始。我们采取从-1开始的,这样j=next[j]好写。

    以"ABCDABD"为例,

    - "A"的前缀和后缀都为空集,共有元素的长度为0;
    - "AB"的前缀为[A],后缀为[B],共有元素的长度为0;
    - "ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;
    - "ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;
    - "ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1;
    - "ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2;
    - "ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。

    所以这里他的next数组是[-1, 0, 0, 0, 0, 1, 2]。(next[i]表示长度为i的字符串前缀的上述共有前后缀)

    5.KMP的比较算法和Next数组的生成算法很像的,相差之处一句next[j]=k;即求next数组的赋值,j的初始值也不一样。

    参考:

    http://www-igm.univ-mlv.fr/~lecroq/string/node8.html

    http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

     在下面的实现中,因为s.length()是unsigned int,所以先转化成int,否则和-1比较会有问题。因为next数组第一个是-1,所以先设置好,然后j也设为-1。

    void get_next(const string &t, vector<int> &next) {
        next.resize(t.size());
        int i = 0;
        int j = -1;
        next[0] = -1;
        while(i < t.size() - 1) {
            if(j == -1 || t[i] == t[j]) {
                next[++i] = ++j;
            }
            else {
                j = next[j];
            }
        }
    }
    

      

    int KMP(const string &t, const string &s) {
        vector<int> next;
        get_next(t, next);
        int i = 0;
        int j = 0;
        int slen = s.length();
        int tlen = t.length();
        while(i < slen && j < tlen) {
            if (j == -1 || t[j] == s[i]) {
                i++;
                j++;
            }
            else {
                j = next[j];
            }
        }
        if(j == tlen)
            return i - j;
        else
            return -1;
    }
    

      

  • 相关阅读:
    主引导扇区的理解
    敏捷的思考
    架构学习笔记
    操作系统笔记
    Docker学习笔记
    技术面试-国外人谈经验
    硬盘的原理学习
    linux压缩和解压命令总结
    好的技术团队和差的技术团队的区别在于技术架构前瞻性和适应变化的能力
    管理者的本质其实就是一个服务者,服务下属的
  • 原文地址:https://www.cnblogs.com/lautsie/p/3228877.html
Copyright © 2011-2022 走看看