Period II - FZU 1901(KMP->next)

题目大意:给你一个字符串 S ,N = |S|,如果存在一个 P (1<=P<=N),并且满足 s[i] = s[P+i] (i = {0...N-P-1} ),求出来所有的 P 然后输出.
 
分析:其实就是这个字符串的后缀与前缀的最大匹配 next[N],然后用最大匹配的串继续找匹配的前缀,比如下面的数据:
 
aaabaaa:--> P = 4  <---> next[7] = 3
aaabaaa:--> P = 5  <---> next[3] = 2
aaabaaa:--> P = 6  <---> next[2] = 1
aaabaaa:--> P = 7  <---> next[1] = 0
 
比较明显的可以看出来怎么求这些数了吧.....
 
代码如下:
=========================================================================================================================
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;

const int MAXN = 1e6+7;

char s[MAXN];
int Next[MAXN], ans[MAXN];

void GetNext(char s[], int len)
{
    int i=0, j=-1;
    Next[0] = -1;

    while(i<len && j<len)
    {
        if(j==-1 || s[i]==s[j])
            Next[++i] = ++j;
        else
            j = Next[j];
    }
}

int main()
{
    int T, t=1;

    scanf("%d", &T);

    while(T--)
    {
        scanf("%s", s);

        int len = strlen(s);

        GetNext(s, len);

        int cnt = 0, k=len;

        while(Next[k] != 0)
        {
            ans[cnt++] = len-Next[k];
            k = Next[k];
        }

        printf("Case #%d: %d\n", t++, cnt+1);
        for(int i=0; i<cnt; i++)
            printf("%d ", ans[i]);
        printf("%d\n", len);
    }

    return 0;
}
/**
2
aaabaaa

Case #1: 4
4 5 6 7
**/

 

posted @ 2015-08-19 18:22  无忧望月  阅读(120)  评论(0编辑  收藏  举报
levels of contents