您的位置:首页 > 其它

POJ2752 Seek the Name, Seek the Fame

2016-06-26 23:36 330 查看
问题链接:POJ2752 Seek the Name, Seek the Fame

读懂题后知道,这个题要算的是,给定一个字符串s,有哪些长度的s的前缀,同时也是s的后缀。

首先明确一下前缀和后缀的概念。字符串s的前缀是指,从s的开始字符到s的任意字符为止的子串。字符串s的后缀是指,从s的任意字符到s的最后字符为止的子串。

这个问题利用KMP算法的next[]数组来解。首先对于输入的字符串s,计算其next[]数组。然后,根据next[]数组的值进行进一步的计算。

还需要知道的是next[]数组的定义。对于字符串s的第i个字符s[i],next[i]定义为字符s[i]前面最多有多少个连续的字符和字符串s从初始位置开始的字符匹配。

从后到前匹配前缀和后缀。如果前缀与后缀匹配,则下一个前缀与后缀匹配的字符串只能在前缀中。

AC程序如下:

/* POJ2752 Seek the Name, Seek the Fame */

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

char s[400000+1];
int next[400000+1];
int result[400000+1];

void setnext(char s[], int next[], int len)
{
next[0] = -1;

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

int main(void)
{
int count, t, i;

while(scanf("%s", s) != EOF) {
int len = strlen(s);

// 计算next[]数组值
setnext(s, next, len);

// 计算结果:从字符串的尾部开始,下一个只能在与后缀相同的前缀字符串中
count = 0;
t = next[len - 1];
while(t != -1) {
if(s[t] == s[len - 1])
result[count++] = t + 1;
t = next[t];
}

// 输出结果
for(i=count-1; i>=0; i--)
printf("%d ", result[i]);
printf("%d\n", len);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: