POJ 2752 Seek the Name, Seek the Fame

题目大意:

        有一只聪明的小猫擅长给新生儿取名字,它取名字的算法依据如下,先将父母的名字连接成一个新的字符串,然后从这个字符串中寻找其实前缀又是后缀的字符串,将该字符串作为孩子的名字(可能会有好几个这样的字符串)。

        现有多个测例(测例数题中给出),每个测例都会给以个字符串,长度为[1, 400000],对于每个测例打印出所有可能的前后缀字符串的长度,按照递增序列打印出来。

题目链接

注释代码:

/*   
 * Problem ID : POJ 2752 Seek the Name, Seek the Fame 
 * Author     : Lirx.t.Una   
 * Language   : C   
 * Run Time   : 110 ms   
 * Run Memory : 3632 KB   
*/ 

#include <string.h>
#include <stdio.h>

//注意:next数组所记录的正好就是既是前缀又是后缀的字符串
//next[len]为最长的前后缀字符串的末尾下标
//next[ next[len] ]即为第二场的前后缀字符串的末尾下标
//因此类推可以用递归找出所有前后缀字符串
//递归结尾就是下标为0
//由于下标是从1开始计的,因此下标就等于前后缀字符串的长度

#define	MAXLEN		400002

char	s[MAXLEN];//string
int		nxt[MAXLEN];

void
bd_nxt(int len) {

	int		i, j;

	nxt[1] = 0;
	for ( j = 0, i = 2; i <= len; i++ ) {
	
		while ( j > 0 && s[j + 1] != s[i] )
			j = nxt[j];

		if ( s[j + 1] == s[i] )
			j++;

		nxt[i] = j;
	}
}

void
out(int x) {//递归打印数组长度

	if ( !nxt[x] ) {
	
		printf("%d ", x);
		return ;
	}

	out( nxt[x] );
	printf("%d ", x);
}

int
main() {

	int		len;//字符串长度

	while ( ~scanf("%s", s + 1) ) {

		len = strlen(s + 1);
		bd_nxt(len);
		out(len);
		putchar('\n');
	}

	return 0;
}

无注释代码:

#include <string.h>
#include <stdio.h>

#define	MAXLEN		400002

char	s[MAXLEN];
int		nxt[MAXLEN];

void
bd_nxt(int len) {

	int		i, j;

	nxt[1] = 0;
	for ( j = 0, i = 2; i <= len; i++ ) {
	
		while ( j > 0 && s[j + 1] != s[i] )
			j = nxt[j];

		if ( s[j + 1] == s[i] )
			j++;

		nxt[i] = j;
	}
}

void
out(int x) {

	if ( !nxt[x] ) {
	
		printf("%d ", x);
		return ;
	}

	out( nxt[x] );
	printf("%d ", x);
}

int
main() {

	int		len;

	while ( ~scanf("%s", s + 1) ) {

		len = strlen(s + 1);
		bd_nxt(len);
		out(len);
		putchar('\n');
	}

	return 0;
}

单词解释:

seek:vt, 寻找,寻求

fame:n, 名声,名望

tramp:n, 流浪者; vt, 流浪,踩踏,踩(走过)

hill:n, 小山,丘陵

dale:n, 山谷,排水口

newly-born:adj, 新生的

innovative:adj, 革新的,创新的

prefix:n, 前缀

suffix:n, 后缀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值