POJ2752_Seek the Name, Seek the Fame_KMP_对next数组的运用

来源:互联网 发布:多个相同表格数据提取 编辑:程序博客网 时间:2024/04/30 11:29

题意:

给一个串s,求他所有的前缀和后缀相等的时候的子串长度,按从小到大输出

题解:

刚开始我也知道是next数组的运用,但是想了半天也没发现有什么练习,想模拟一遍找规律,但是失败了,无奈上网搜解题报告,发现都是next数组回溯就可以了,自己试了一下发现果真是这样= =,但是心中一万个不懂啊!!网上的题解一个比一个简单,解释也一笔带过,不过后来查到一个文档上面有图,虽然也是两三行就说完了,但是看着图才发现其中的奥妙。


先说规律,就好比他给的例子:

          ababcababababcabab

一共18位,next数组内容是:-1,0,0,1,2,0,1,2,3,4,3,4,3,4,5,6,7,8,9

next[n]=9;next[9]=4;next[4]=2;next[2]=0;

逆序输出,0舍掉,再加一个最后全部的18(因为整个串为前缀的话,整个串也为后缀,两者必相等)

就是2,4,9,18为正确答案了


下面解释为什么会是这种规律


看上图,next[18]=9,说明图中红色和绿色完全相同,此时第二大的前缀跟后缀相等即为next[n]=9;(第一大是母串本身18)

再到下一图,next[9]=4,表示前9格中,前4个(深蓝)和后四个(天蓝)相同,而前9个和后9个又相同,可推出前4个和后4个相同(两个深蓝一样)

再到下一图,next[4]=2,表示前4格中,前两个(黄色)和后两个(黄色)相同,而对于母串而言,前4个和后四个两个深蓝相同,可得前两个和后两个相同(两个黄色一样)

而next[2]=0,表示前2格中没有相同的前缀和后缀了,所以循环终止


这样通过next[]数组本身的含义我们推出了以上公式

题目:

Seek the Name, Seek the Fame
Time Limit: 2000MS Memory Limit: 65536KTotal Submissions: 9653 Accepted: 4631

Description

The little cat is so famous, that many couples tramp over hill and dale to Byteland, and asked the little cat to give names to their newly-born babies. They seek the name, and at the same time seek the fame. In order to escape from such boring job, the innovative little cat works out an easy but fantastic algorithm:

Step1. Connect the father's name and the mother's name, to a new string S.
Step2. Find a proper prefix-suffix string of S (which is not only the prefix, but also the suffix of S).

Example: Father='ala', Mother='la', we have S = 'ala'+'la' = 'alala'. Potential prefix-suffix strings of S are {'a', 'ala', 'alala'}. Given the string S, could you help the little cat to write a program to calculate the length of possible prefix-suffix strings of S? (He might thank you by giving your baby a name:)

Input

The input contains a number of test cases. Each test case occupies a single line that contains the string S described above.

Restrictions: Only lowercase letters may appear in the input. 1 <= Length of S <= 400000.

Output

For each test case, output a single line with integer numbers in increasing order, denoting the possible length of the new baby's name.

Sample Input

ababcababababcababaaaaa

Sample Output

2 4 9 181 2 3 4 5


Run IDUserProblemResultMemoryTimeLanguageCode LengthSubmit Time11775626chengtbf2752Accepted2632K141MSC++731B2013-07-13 14:29:55


代码:


#include<stdio.h>#include<string.h>#define N 400005int ans[N];char str[N];int next[N];int n;void get_next(){int pos=2;int cnd=0;next[0]=-1;next[1]=0;while (pos<=n){if (str[pos-1]==str[cnd]){cnd++;next[pos]=cnd;pos++;}else if(cnd>0){cnd=next[cnd];}else{next[pos]=0;pos++;}}}int main(){int i,j,k;while (scanf("%s",str)!=EOF){n=strlen(str);get_next();i=n;j=1;while (1){if (next[i]<=0){break;}else{ans[j]=next[i];j++;i=next[i];}}for ( k = j-1; k >=1 ; k--){printf("%d ",ans[k]);}printf("%d\n",n);}return 0;}