题解报告:poj 2752 Seek the Name, Seek the Fame(kmp前缀表prefix_table的运用)
Description
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
Restrictions: Only lowercase letters may appear in the input. 1 <= Length of S <= 400000.
Output
Sample Input
ababcababababcabab
aaaaa
Sample Output
2 4 9 18
1 2 3 4 5
解题思路:题目的意思就是找出给定串str中所有前缀子串和所有后缀子串完全匹配的子串长度。
首先要明确一下字符串前缀和后缀的概念:
字符串str的前缀是指从str的第一个字符开始到任意一个字符为止的子串;
字符串str的后缀是指从str的任意一个字符开始到最后一个字符为止的子串。
拿题目中字符串"alala"举个例子:
其所有前缀为a al ala alal alala
其所有后缀为a la ala lala alala
因此所有前缀子串和所有后缀子串中完全匹配的子串有a、ala、alala,其对应长度为1、3、5。
怎么计算这样匹配子串的长度呢?拿之前对模式串计算前缀表来分析一下过程:第一个样例是ababcababababcabab,len=18,其前缀表如下:
字符串的下标 0 1 3 5 6 7 8 10 11 12 13 14 15 16 17
字符串 a b a b c a b a b a b a b c a b a b
前缀表值 -1 0 0 1 0 1 2 3 3 4 3 4 5 6 7 8
因为字符串str自身就是最长的完全匹配的前后缀子串,而prefix[i]表示前i-1个字符组成的子串中最长公共前后缀长度,即str[i]前面有prefix[i]个字符与从str第一个字符开始连续prefix[i]个字符完全匹配,所以我们从后往前匹配,如果i位置前的子串有前缀和后缀匹配即prefix[i]!=0,则下一次匹配就在前缀子串找(即i=prefix[i]位置前面的子串),并且记录一下构成匹配的前缀子串的后一个位置即为字符串str前后缀完全匹配的长度,第一次为out[0]=18,如图所示。
令j=18,则下一次匹配为j=prefix[j=18]=9,out[1]=9,即此时前缀为ababcabab与后缀(下标从9开始到最后一个字符构成的子串ababcabab)是完全匹配的;
继续往前缀子串中匹配即j=prefix[j=9]=4,out[2]=4,即此时前缀子串为abab和后缀子串(下标从14开始到最后一个字符构成的子串abab)也是完全匹配的;
继续往前缀子串中匹配即j=prefix[j=4]=2,out[3]=2,即此时的前缀子串ab和后缀子串(下标从16开始到最后一个字符构成的子串ab)也是完全匹配的;
继续往前缀子串中匹配即j=prefix[j=2]=0,说明此时再无前后缀匹配,退出匹配过程,所以最终反序输出out数组为2 4 9 18。以上最终结果可以列举所有前后缀子串自行验证一下。
因此,本题的做法就是先计算好给定字符串的前缀表,再从j为字符串长度开始往前匹配,终止条件为j!=0,同时记录一下每次匹配的最长前后缀公共长度,最后反序输出即可。
AC代码:
#include<string.h>
#include<cstdio>
const int maxn=4e5+;
char pattern[maxn];
int out[maxn],prefix[maxn],lenb;
void get_prefix_table(){
int j=,pos=-;
prefix[]=-;
while(j<lenb){
if(pos==-||pattern[pos]==pattern[j])prefix[++j]=++pos;
else pos=prefix[pos];
}
}
int main(){
while(~scanf("%s",pattern)){
lenb=strlen(pattern);
get_prefix_table();
/*for(int i=0;i<=lenb;++i)
printf("%3d",i);
printf("\n");
for(int i=0;i<=lenb;++i)
printf("%3d",prefix[i]);
printf("\n");*/
int k=,j=lenb;
while(j!=){out[k++]=j;j=prefix[j];}//直到最长公共前后缀长度为0为止
for(int i=k-;i>=;--i)
printf("%d%c",out[i],i==?'\n':' ');
}
return ;
}
题解报告:poj 2752 Seek the Name, Seek the Fame(kmp前缀表prefix_table的运用)的更多相关文章
- POJ 2752 Seek the Name,Seek the Fame(KMP,前缀与后缀相等)
Seek the Name,Seek the Fame 过了个年,缓了这么多天终于开始刷题了,好颓废~(-.-)~ 我发现在家真的很难去学习,因为你还要陪父母,干活,做家务等等 但是还是不能浪费时间啊 ...
- (KMP)Seek the Name, Seek the Fame -- poj --2752
http://poj.org/problem?id=2752 Seek the Name, Seek the Fame Time Limit: 2000MS Memory Limit: 65536 ...
- Seek the Name, Seek the Fame POJ - 2752
Seek the Name, Seek the Fame POJ - 2752 http://972169909-qq-com.iteye.com/blog/1071548 (kmp的next的简单应 ...
- KMP POJ 2752 Seek the Name, Seek the Fame
题目传送门 /* 题意:求出一个串的前缀与后缀相同的字串的长度 KMP:nex[]就有这样的性质,倒过来输出就行了 */ /************************************** ...
- POJ 2752 Seek the Name, Seek the Fame [kmp]
Seek the Name, Seek the Fame Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17898 Ac ...
- poj 2752 Seek the Name, Seek the Fame【KMP算法分析记录】【求前后缀相同的子串的长度】
Seek the Name, Seek the Fame Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14106 Ac ...
- poj 2752 Seek the Name, Seek the Fame(KMP需转换下思想)
Seek the Name, Seek the Fame Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10204 Ac ...
- POJ 2752 Seek the Name, Seek the Fame(next数组运用)
Seek the Name, Seek the Fame Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 24000 ...
- poj 2752 Seek the Name, Seek the Fame (KMP纯模版)
Seek the Name, Seek the Fame Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 13840 Ac ...
随机推荐
- the attribute buffer size is too small 解决方法
在进行查询的时候引发The attribute buffer size is too small错误解决 http://bbs.esrichina-bj.cn/esri/viewthread.php? ...
- Python - 多次检查后缀名(endwith)
在通过后缀名查找类型文件的时候, 多次使用endwith, 使用元组(tuple), 简化操作. 此类方式, 也能够应用于if语句多次类似检測. 代码 # 列出目录内全部代码 def list_dic ...
- linuxc线程信号-pthread_cond_wait理解
pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t*mutex)函数 传入的參数mutex用于保护条件,由于我们在调用pthread_con ...
- cocos2d-x 2.0下怎样让BOX2D DEBUG DRAW的方法笔记
原文链接: 这两天玩 cocos2d-x 和 box2d,发现 cocos2d-x 2.0 版本号要使用老方法 debug 渲染会出错.于是找到了新方法来 debug draw: 首先在你的头文件中添 ...
- Linux登录自动切换root账户与历史命令优化
1:当我们Linux系统优化完成,会使用oldboy用户远程连接CRT登录,每次连接都需要使用sudo su - 或者su - 输入密码登录,请问如何在CRT连接的时候自动的切换到root账户,(提示 ...
- LuaInterface简单介绍
LuaInterface简单介绍 Lua是一种非常好的扩展性语言.Lua解释器被设计成一个非常easy嵌入到宿主程序的库.LuaInterface则用于实现Lua和CLR的混合编程. (一)Lua f ...
- boost的内存管理
smart_ptr raii ( Resource Acquisition Is Initialization ) 智能指针系列的都统称为smart_ptr.包含c++98标准的auto_ptr 智能 ...
- Unable to find a team with the given Team ID或者Failed to code sign的问题解决
Unable to find a team with the given Team ID或者Failed to code sign的问题解决 1:问题描述(注:这种情况一般是下载并打开别人项目时) F ...
- go 泛型 Go中不包含的特性
人Andrei Alexandrescu:“Go所走的路线在一些问题上持有极其强硬和死板态度,这些问题有大有小.在比较大的方面,泛型编程被严格控制,甚至贬低到只有"N"个字:有关泛 ...
- how to create modals with Bootstrap
In this tutorial you will learn how to create modals with Bootstrap. Creating Modals with Bootstrap ...