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

其实这道题用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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值