IT民工
加油!

给出一个字符串A,求A有多少个前缀同时也是后缀,从小到大输出这些前缀的长度

分析:KMP

对于长度为len的字符串,由next的定义知:

A[0]A[1]...A[next[len]-1]=A[len-next[len]]...A[len-1]此时A[0]A[1]...A[next[len]-1]

为一个符合条件的前缀

有A[0]A[1]....A[next[next[len]]-1] = A[len-next[next[len] - next[next[len]]]...A[next[len]-1],

故A[0]A[1]....A[next[next[len]]-1]也是一个符合条件的前缀

故从len=>next[len]=>next[next[len]] ....=>直到某个next[]为0均为合法答案,

注意当首位单词相同时,也为答案。

/*Accepted    2632K    157MS    C++    845B    2012-08-01 16:36:07*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

const int MAXN = 400040;
char t[MAXN];
int next[MAXN], ans[MAXN], len;

void Make_Next()
{
    int i = 0, j = -1;
    next[0] = -1;
    len = strlen(t);
    while(i < len)
    {
        if(-1 == j || t[i] == t[j])
        {
            ++ i, ++ j;
            next[i] = j;
        }
        else
            j = next[j];
    }
}

void print(int ith)
{
    int i = 0;
    while(ith)
    {
        ans[i ++] = ith;
        ith = next[ith];
    }
    i --;
    for( ; i >= 0; i --)
    {
        printf("%d", ans[i]);
        if(i) printf(" ");
    }
    printf("\n");
}

int main()
{
    while(scanf("%s", t) == 1)
    {
        Make_Next();
        print(len);
    }
    return 0;
}

 

 

 

 

posted on 2012-08-01 16:55  找回失去的  阅读(190)  评论(0编辑  收藏  举报