码迷,mamicode.com
首页 > 其他好文 > 详细

EX_KMP算法总结

时间:2014-08-21 21:01:04      阅读:2040      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   strong   for   ar   2014   art   

EX_KMP算法总结

By viv

2014-8-9 0:30

吐槽1:字符串神马的我最讨厌了,但不学不行啊。TAT

吐槽2:写这东西差点错过CF(codeforces).

今天学了ex_kmp,故总结一下。(记性不好,学了的东西,说不定过两天就忘了)

先说说ex_kmp算法求得什么:

给定字符串T,P, n = |T| , m = |P|,定义ex[i] = T[i …n]和P的最长公共前缀的长度。

这就是ex_kmp问题,ex_kmp算法就死在线性时间内求得所有的ex[i]。

我们可以发现,如果ex[i] = m,则P在T中出现过,且位置为i,这正是KMP所求得东西。由此可见ex_kmp算法是对kmp的扩展。

下面说一下ex_kmp算法的流程(下表从0开始,当前节点为k,设P自己进行ex_kmp得到的ex数组为f数组):

假设ex[0,k)已经求好,在匹配中,到达的最远距离为p,即p为i + ex[i]的最大值,我们设取最大值的i为a。

这样我们可以得到以下几个关系:

T[a,p] = P[0,p - a]

T[k,p] = P[k – a,p - a]

这样,我们可以分两种情况:(用mspaint画的,很丑,字母大小写问题也不要在意了,明白就行)

情况1:

bubuko.com,布布扣

如上图,如果 K + f[k - a] < p的话,显然,图中灰色部分一定相同,蓝色部分一定不同。这样一来,f[k] = f[k - a] 且 a , p 的值不变。

情况2:

bubuko.com,布布扣

如上图,如果K+f[k - a] >= p的话,则,图中蓝色部分相同,紫色部分未知。这种情况下,我们就可以直接从p+1位开始匹配,直到失配。然后更新a , p的值。

就这样,整个算法已经完结了。至于f数组,自己和自己匹配一下就可以啦。

ex_kmp模板:

void getFail(char *T)
{
    int idx = 0, mx = 0,n = strlen(T);
    f[0] = n;
    for (int i = 1; i < n; i++)
    {
        if (mx > i + f[i - idx])
        {
            f[i] = f[i - idx];
            continue;
        }
        f[i] = max(mx - i, 0);
        while (T[i + f[i]] == T[f[i]])
            f[i]++;
        if (i + f[i] > mx)
            mx = i + f[i], idx = i;
    }
}

void ex_kmp(char *T, char *P)
{
    getFail(P);
    int idx = 0, mx = 0,n = strlen(T);
    for (int i = 0; i < n; i ++)
    {
        if (mx > i + f[i - idx])
        {
            ex[i] = ex[i - idx];
            continue;
        }
        ex[i] = max(mx - i, 0);
        while ((i + ex[i] < n) && T[i + ex[i]] == P[ex[i]])
            ex[i]++;
        if (i + ex[i] > mx)
            mx = i + ex[i], idx = i;
    }
}

 

 

END

EX_KMP算法总结,布布扣,bubuko.com

EX_KMP算法总结

标签:style   blog   http   strong   for   ar   2014   art   

原文地址:http://www.cnblogs.com/vivym/p/3927955.html

(0)
(5)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!