• KMP算法


      看严蔚敏的数据结构看得云里雾里,后来看了其它博客才了解得比较透彻。其实算法的大体思路并不难理解。最原始的字符串匹配算法是将匹配串与模式串对齐,然后从左向右一个个比较,如果失配则模式串向右移动一个单位,这样没有利用前面部分匹配的信息,时间复杂度为O(n*m)。

      KMP算法则是利用了部分匹配的信息,并以此来判断失配时向右移动多少,时间复杂度为O(n+m)。设i指向匹配串的当前匹配字符,j指向模式串的当前匹配字符,若失配,则j=next[j]。

    因此关键就是求模式串的next数组。严蔚敏的教材是针对从1开始的数组的,而且对next数组的值的意义也没说清楚,所以在那里卡了很久,看了其他人的博客才清楚。 

    要理解next数组还是比较难的,教材上的思路是这样的:

    已知next[0]=-1,next[1]=0,设next[j]=k,若t[j]==t[k]且t[j+1]!=t[k+1],则next[j+1] =next[j]+1;若t[j]==t[k]且t[j+1]==t[k+1],则next[j+1] = next[k+1]。若t[j]!=t[k],可以看成模式串自身匹配问题,将模式向右滑动到next[k],若还是不匹配,就滑动到next[next[k]],如果最后还是不匹配则就肯定会滑动到next[0]。所以下面的程序会看到if(j ==-1 ||...)

    next数组的取值(设模式串为t[])

      next[0]=-1 任何模式串的第一个模式值规定为-1

      next[j] = -1 (j>k≥1) 若t[j] = t[0]且前k个字符不等于j前面的k个字符,则模式值为-1(这表示第一个字符都无法匹配)

      next[j] = k   (j>k≥1)t[j]!=t[k]且前k个字符等于j前面的k个字符

      next[j] = 0  其它情况。这里有三种情况,一种是对于j>k≥1,前k个字符不等于j前面的k个字符且t[j]!=t[0],自然需要滑动到第一个字符再开始匹配;一种是对于j>k≥1,前k个字符等于j前面的k个字符且t[j]==t[0],让它直接滑动到第一个字符(因为next[k]会是0),能够减少比较次数;还有一种就是next[1]总是为0

    代码如下

    inline void get_next(string t, int next[])
    {
        int i = 0, j = -1;
        next[0] = -1;
        while (i<t.length())
        {//j在每次循环开始都表示next[i]的值,同时也表示需要比较的下一个位置 
            if (j == -1 || t[i] == t[j])
            { 
                ++i; 
                ++j;
                if (t[i] != t[j])
                    next[i] = j;
                else
                    next[i] = next[j];
            }
            else j = next[j];
        }
    }
    int KMP(string s, string t)
    {
        int i = 0, j = 0;
        int s_len = s.length();
        int t_len = t.length();
        int *next = new int[t_len + 1];
        get_next(t, next);
        while (i<s_len && j<t_len)
        {
            if (j==-1 || s[i] == t[j]) { ++i; ++j; }
            else
                j = next[j];
        }
        if (j>=t_len) return i - t_len; //匹配成功
        else return -1;
    }
  • 相关阅读:
    CentOS 7.x 二进制方式安装mysql5.7.24
    Java集合框架学习总结
    deque 归纳
    KMP学习笔记
    luogu 3393 逃离僵尸岛
    luogu 1280 尼克的任务
    HDU4871 Shortest-path tree(点分治)
    BZOJ4399 魔法少女LJJ
    BZOJ4771 七彩树
    (BUILDER)建造者与(FACTORY)工厂模式 的比较
  • 原文地址:https://www.cnblogs.com/tonychen-tobeTopCoder/p/5170246.html
Copyright © 2020-2023  润新知