• 扩展KMP


    扩展KMP可以快速求出T与S每个后缀的LCP,时间复杂度和空间复杂度都比后缀数组要优良很多。

    const LL N = 200005;
    //扩展KMP
    int nex[N];//T串的每一个后缀与T的LCP
    int ext[N];
    char S[N];
    char T[N];
    void getNex()
    {
        //int len = T.length();
        int len = strlen(T);
        nex[0] = len;
        int i=0, j=0,po=1;
        while (i + 1 < len&&T[i] == T[i + 1])i++;
        nex[1] = i;
        for (i = 2; i < len; i++)
        {
            int P = nex[po] + po;
            if (i + nex[i - po] < P)//(T均为T的后缀)因为T[po]和T[0]匹配,所以T[i]和T[i-po]匹配,那么只要知道nex[i-po],计算最远长度是否超过P
                nex[i] = nex[i - po];
            else
            {
                j = P - i;//nex[i-po]>P-i,所以从P-i往后都是未知的,需要匹配.
                if (j < 0)j = 0;//如果po也没有lcp就会出现负数,就0开始匹配
                while (i + j<len&&T[i + j] == T[j])j++;
                nex[i] = j;
                po = i;//这里if可以不需要,因为如果P不够匹配了,新的j必然>=P
            }
        }
    }
    void exKmp()
    {
        getNex();
        //int lens = S.length();
        //int lent = T.length();
        int lens = strlen(S);
        int lent = strlen(T);
        int i=0, j=0, po=0;
        while (i+j<lens&&j<lent&&S[i + j] == T[j])j++;
        ext[i] = j;
        po = 0;
        for (i = 1; i < lent; i++)
        {
            int P = ext[po] + po;
            if (i + nex[i - po] < P) ext[i] = nex[i - po];//此处用nex而不是ext的原因是,需要通过T串后缀的lcp找到尽可能匹配的长度
            else
            {
                j = P - i;
                if (j < 0)j = 0;
                while (i + j<lens&&j<lent&&S[i + j] == T[j])j++;
                ext[i] = j;
                po = j;
            }
        }
    }
  • 相关阅读:
    cocos2d-x 动画特效集合
    cocos2d-x 2.0 序列帧动画 深入分析
    cocos2d-x 的CCObject与autorelease 之深入分析
    cocos2d-x 2.0 拖尾效果分析
    Cocos2d-x 2.0 自适应多种分辨率
    cocos2d-x学习笔记
    golang中并发sync和channel
    深入学习golang(2)—channel
    golang手动管理内存
    golang 内存池
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/7620338.html
Copyright © 2020-2023  润新知