poj2752 KMP的next[]函数的理解 或者 扩展的KMP

来源:互联网 发布:人工智能的发展进程 编辑:程序博客网 时间:2024/05/17 23:43

其实这道题用KMP的next[]也挺方便的,用扩展的KMP更好理解一点。

(1)用KMP的next[]:

求出next[]函数之后,length是最长的,也就是本身,next[lenth]是次长的,next[next[length]]又次之。。。

直到next[]为-1为止。这样得到的序列正好是降序的,反着输出来就ok了。

为什么这么做?由next函数特性,好好想一下,肯定就很容易明白了。或者自己举个例子,把它的next[]求出来,看一下就明白了。

(2)扩展的KMP

扩展的KMP是求得前缀。next[i]表示从i到length,与0到length的最长的匹配。

(哎呀,我这里就不啰嗦它了,不知道的,说了也没用,知道的,我这一说就明白了。)

我这里给一个讲解扩展的KMP链接,有兴趣的可以看看:

http://www.cnblogs.com/yefeng1627/archive/2012/12/24/2830979.html

求出next之后,判断next[i]==length-i,就是前后缀匹配的长度。

所以i=length-1到i==0,逆着输出出来就ok了。

我是用第二中方案做的,代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAX = 400011;int next[MAX],extand[MAX];char ch[MAX];void getnext(char *T){// next[i]: 以第i位置开始的子串 与 T的公共前缀 int i,length = strlen(T); next[0] = length; for(i = 0;i<length-1 && T[i]==T[i+1]; i++); next[1] = i; int a = 1; for(int k = 2; k < length; k++){    int p = a+next[a]-1, L = next[k-a];    if( (k-1)+L >= p ){    int j = (p-k+1)>0? (p-k+1) : 0;    while(k+j<length && T[k+j]==T[j]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较        next[k] = j, a = k;    }    else next[k] = L; }}int main(){    int i,j;    while(scanf("%s",ch)!=EOF)    {        getnext(ch);        int length=strlen(ch);        for(i=length-1;i>=0;i--)        {            if(next[i]==length-i)                printf("%d ",next[i]);        }        printf("\n");    }    return 0;}


 

0 0