poj 2752 kmp(next数组的应用)

Seek the Name, Seek the Fame

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 16036   Accepted: 8159

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

ababcababababcabab
aaaaa

Sample Output

2 4 9 18
1 2 3 4 5

此题意思是让输出字符串中所有具有相同前后缀时的字符串长度。

已知 next数组中存放的是当前字符之前的字符串中具有相同前后缀的长度,

例如:next[i]=5;表示从字符串开始到下标为 i-1时,具有长度为5的相同前后缀子串

字符串:ababcababababcabab

下标:    0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18

字符:    a   b   a   b   c   a   b   a   b   a   b   a   b   c   a   b   a   b

next: -1   0   0   1   2   0   1   2   3   4   3   4   3   4   5   6   7   8   9

1、长度为 18 时,字符串为 ababcababababcabab,前缀 ababcabab,后缀 ababcabab,输出18;

2、长度为 9 时,字符串为 ababcabab,前缀 abab,后缀abab,输出 9;

3、长度为 4 时,字符串为 abab,前缀 ab,后缀 ab,输出 4;

4、长度为 2 时,字符串为 ab,前缀 a,后缀 b,此时前后缀不相同,输出此时的字符串长度 2,并结束;

(因为字符串是从后向前一一查找判断的,所以当找到不想同的前后缀时既查找完毕,输出并结束)

......

如果还不明白,我就仍然以上述例子说,next[18]=9;意思是说,此字符串有长度为 9 的相同前后缀, 如上 1 所示,

设字符串长度为 9,此时next[9]=4,表示在此长度为 9 的前缀中,又有长度为 4 的相同的前后缀,

设字符串长度为 4,此时next[4]=2;.............

依次进行....

具体代码:
#include <stdio.h>
#include <string.h>
char s[400005];
int next[400005];
int ans[400005];
void Make_next(int len)
{
	int i=0,j=-1;
	memset(next,0,sizeof(next));
	next[0]=-1;
	while(i<len)
	{
		if(j==-1 || s[i]==s[j])
		{
			i++; j++;
			next[i]=j;
		}
		else
			j=next[j];
	}
}
int main()
{
	while(scanf("%s",&s)!=EOF)
	{
		int len=strlen(s);
		Make_next(len);
		int i,j=0;
		memset(ans,0,sizeof(ans));
		for(i=len;next[i]!=-1;)//直到找到没有前缀后缀相同为止
		{
			ans[j++]=i;//记录具有相同前后缀时的字符串的长度
			i=next[i];
		}
		for(i=j-1;i>=0;i--)
			printf("%d ",ans[i]);
		printf("\n");
	}
	return 0;
}
时间: 2024-11-02 15:25:18

poj 2752 kmp(next数组的应用)的相关文章

[kuangbin带你飞]专题十六 KMP &amp; 扩展KMP &amp; Manacher H - Seek the Name, Seek the Fame POJ - 2752(kmp的next数组应用)

H - Seek the Name, Seek the Fame POJ - 2752 题目链接:https://vjudge.net/contest/70325#problem/H 题目: 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. Th

POJ 2752 KMP中next数组的理解

感觉这里讲的挺好的.http://cavenkaka.iteye.com/blog/1569062 就是不断递归next数组.长度不断减小. 题意:给你一个串,如果这个串存在一个长度为n的前缀串,和长度为n的后缀串,并且这两个串相等,则输出他们的长度n.求出所有的长度n. 思路:KMP中的get_next().对前缀函数next[]又有了进一步的理解,str[1]~~str[next[len]]中的内容一定能与str[1+len-next[len]]~~str[len]匹配(图1).然后呢我们循

POJ 2752+KMP+利用next数组性质求出所有相同的前缀和后缀

题目链接:点击进入 这个题目要求所有相同的前缀和后缀的长度.我们可以利用KMP算法中next数组的性质,在next[len]这个点不断的失配下去,这样就可以将所有相同的前后缀的长度求出来.还要注意这个中整个串的长度也可以看成是一个合法的解. 代码如下: #include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn=400000+100; char str

poj 2752 kmp的next数组

题目大意: 求一个字符串中某一个既是前缀又是后缀的前缀的结尾下标: 基本思路: 从_next[len]开始找_next[_next[len]],再找_next[_next[_next[len]]],一直找到0: 代码如下: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 4000

hdu 1686 &amp; poj 2406 &amp; poj 2752 (KMP入门三弹连发)

首先第一题 戳我穿越;http://acm.hdu.edu.cn/showproblem.php?pid=1686 题目大意好理解,每组输入一个子串和一个母串,问在母串中有多少个子串? 文明人不要暴力,因为宽度会超时,除去暴力后这就是赤果果的KMP KMP的重点在于在子串中建立一个匹配表,记录 到每一位的 前缀后缀 中的相同的子子串的最大长度 然后在比较子母串的时候当遇到不同时 后移的位数就是前面相同的个数减去对应的匹配表例的数 额 讲的不清不楚 那推荐戳这里:http://kb.cnblogs

POJ 2752 (KMP)

题目链接:http://poj.org/problem?id=2752 题意:给一个字符串,判断前缀和后缀是相同的位置,把这些位置从小到大输出出来. 题解:通过字符串得到next数组,然后从next[len]开始.其值就是最后一个是相同前缀后缀的位置,然后,i=next[i],就是不断的向前找,就匹配了过去. 代码如下: 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<

POJ 2406 KMP/后缀数组

题目链接:http://poj.org/problem?id=2406 题意:给定一个字符串,求由一个子串循环n次后可得到原串,输出n[即输出字符串的最大循环次数] 思路一:KMP求最小循环机,然后就能求出循环次数. #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<str

POJ 2752 (KMP 所有可能长度的前缀后缀) Seek the Name, Seek the Fame

题意: 求一个字符串的相同前缀后缀的所有可能的长度,这里该字符串其本身也算自己的前缀和后缀. 分析: 我们知道next数组的性质是,该字符之前的字符串的最大相同前缀后缀. 既然知道了最大的,即next[len]. 递归一次next[ next[len] ],就能求得更小的前缀. 不断的递归把所有所有可能的长度找出来,然后递归输出即可. 1 #include <cstdio> 2 #include <cstring> 3 4 const int maxn = 400000; 5 ch

POJ 2752 深刻理解KMP失配指针

思路:刚开始还在想怎么做,虽然以前是理解了失配指针的用处,但是确实不知道失配指针还有如此用处,其实还有很多用处,我用得少了不懂而已. 比如: i   0  1  2  3  4  5   6  7  8  9  10 11 p[i]  A  B R A  C  A  D  A  B  R  A  无 next[i]  0  0  0  0  1  0   1  0  1   2  3   4 next[11]=4这个肯定可以取了,因为这个后缀等于前缀嘛,然后再查询next[next[11]]=n