题解报告: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 ...
随机推荐
- 微信小程序之 ShoppingCart(购物车)
1.项目目录 2.逻辑层 group.js // pages/group/group.js Page({ /** * 页面的初始数据 */ data: { goodslist: [ { id: &qu ...
- Android NDK 环境搭建
使用最新ndk,直接抛弃cygwin,曾经做Android的项目要用到NDK就必需要下载NDK,下载安装Cygwin(模拟Linux环境用的),下载CDT(Eclipse C/C++开发插件),还要配 ...
- Android Material Design-Maintaining Compatibility(保持兼容性)-(七)
转载请注明出处:http://blog.csdn.net/bbld_/article/details/40634829 翻译自: http://developer.android.com/traini ...
- win10访问共享文件夹提示:引用的账户当前已锁定,且当前可能无法登陆
最近一台电脑访问windows 2008 R2 server的共享文件夹.没有使用域环境. win10界面提示:引用的账户当前已锁定,且当前可能无法登陆. 登陆2008发现,该账户的确锁定.猜测可能该 ...
- [办公应用]如何在WORD中让英文网址可以在字符中间换行
有时候我们写文章,存在中英文混合录入的情况.一般情况下,office 2003的word软件中,会自作聪明的避免单词断行显示,也就是说它会默认尽量把一个单词显示在某一行内,从而避免单词被分开.但有时候 ...
- 2016/3/18 ①PHP基础 ② PHP函数 ③其他函数(随机数、关于日期) ④正则表达式 ⑤字符串处理
一.PHP基础 1,标记和注释 ①<?php?> ②单行注释// 多行注释/** */2, 输出语句 ①echo输出 echo可以输出多个字符串,用逗号隔开. ②print输出 pr ...
- Django值聚合,分组,事物,cookie,session
1,聚合(aggregate):是queryset的一个 终止语句,它返回一个包含键值对的字典,键是的名称是聚合值的标识符,值是计算出来的聚合值,键的名称是按照字段和聚合函数自动生成出来的.用到的内置 ...
- qemu所支持的网卡
1 命令 -net nic 创建一个network interface card,即创建一个网卡,默认是e1000网卡. 2 qemu所支持的网卡类型 2.1 rtl8139 Realtek 10/1 ...
- mysql04--存储过程
过程:若干语句,调用时执行封装的体.没有返回值的函数. 函数:是一个有返回值的过程 存储过程:把若干条sql封装起来,起个名字(过程),并存储在数据库中. 也有不存储的过程,匿名过程,用完就扔(mys ...
- VS2012变化的快捷键
VS2012变化的快捷键: 注释::VS2010是(Ctrl+E,C),VS2012是(Ctrl+K, Ctrl+C),实际操作,按住Ctrl键不放,先按K键,再按C键.相当于Ctrl+K加 Ctrl ...