Period II---fzu1901(Next數組)

題目連接:http://acm.fzu.edu.cn/problem.php?pid=1901php

你一個字符串 s 求出全部知足s[i] == s[i+p] ( 0 < i+p < len )的 p ;算法

kmp中Next[i] 表示前i個字符的前綴和後綴的最大匹配 s[0--x] == s[i-x-1 --- i] ;數組

下面是看別人的解釋:ide

•知識點:KMP算法、對next數組的理解
•KMP算法中next數組的含義是什麼?
•next數組:失配指針
•若是目標串的當前字符i在匹配到模式串的第j個字符時失配,那麼咱們可讓i試着去匹配next(j)
•對於模式串str,next數組的意義就是:
•若是next(j)=t,那麼str[1…t]=str[len-t+1…len]
•咱們考慮next(len),令t=next(len);
•next(len)有什麼含義?
•str[1…t]=str[len-t+1…len]
•那麼,長度爲len-next(len)的前綴顯然是符合題意的。
•接下來咱們應該去考慮誰?
•t=next( next(len) );
•t=next( next (next(len) ) );
• 一直下去直到t=0,每一個符合題意的前綴長是len-t
 
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;

const int N = 1e6+7;

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

void GetNext(char a[], int n)
{
    int i=0, j=-1;
    Next[0] = -1;
    while(i<n)
    {
        if(j==-1 || a[i]==a[j])
            Next[++i] = ++j;
        else
            j = Next[j];
    }
}

int main()
{
    int T, t=1, k, len;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%s", s);
        len = strlen(s);
        GetNext(s, len);
        k = 0;

        for(int j=len; j>0; j=Next[j])
            ans[k++] = len - Next[j];

        printf("Case #%d: %d\n", t++, k);
        for(int i=0; i<k; i++)
            printf("%d%c", ans[i], i==k-1?'\n':' ');
    }
    return 0;
}
View Code
相關文章
相關標籤/搜索