poj 2752 Seek the Name, Seek the Fame【KMP算法分析记录】【求前后缀相同的子串的长度】
| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 14106 | Accepted: 7018 |
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 题意:求所有前缀和后缀相同的子串的长度
题解:首先了解什么是前缀和后缀
1、前缀:从第一位开始依次取字符串中字符所组成的子串 如字符串abcd其前缀为:a,ab,abc,abcd注意abcd也算其前缀
2、后缀:从最后一位开始依次向前取字符串中的字符组成的子串如abcd其后缀为:d,cd,bcd,abcd
我们所求的失配函数f[]其失配值f[i]就是从0到i的前缀后缀相同的最大子串的长度如
求失配函数:
方法一、我们一起求一下这组数据的前后缀(即失配函数的值)f[0]=0;
(不考虑整条字符串本身)
a的前后缀都为空(1位置 f[1]=0)
ab的前缀为a,后缀为b不相等(f[2]=0)
abc的前缀为a,ab后缀为bc,b不相等(f[3]=0)
abcd的前缀为a,ab,abc后缀为bcd,cd,d没有相等的(f[4]=0)
abcda的前缀为a,ab,abc,abcd,后缀为bcda,cda,da,a有相同的前后缀a且长度为1(f[5]=1)
以此类推得到f[6]=2,f[7]=0;
方法二、
另一种方法求失配函数
规定f[0]=f[1]=0(失配函数第0位和第1为毕等0)
给一组数据来说明求的方法:
0 1 2 3 4 5 6 7
a b c d a b d
0 0
第0和第1位已经确定现在从第2位开始求,当求c时我们需要看他前一位的
字符以及前一位的字符的失配值(f[i]值),前一位是b失配值是0,我们就来看
第0位所代表的字符是否和b相同,相同则f[2]=f[1]+1,不同则f[2]=0
这里不同所以f[3]=0,此时数据变为:
0 1 2 3 4 5 6 7
a b c d a b d
0 0 0
第3位,任然比较他的前一位,为c失配值为0我们依然拿d的前一位c同第0位比较
c和a不同所以 f[3]=0;此时数据变为:
0 1 2 3 4 5 6 7
a b c d a b d
0 0 0 0
同理f[4]=0
0 1 2 3 4 5 6 7
a b c d a b d
0 0 0 0 0
第5位 前一位是a失配值为0此时第五位的a等于第0位的a所以f[5]=f[4]+1=1
0 1 2 3 4 5 6 7
a b c d a b d
0 0 0 0 0 1
第6位 前一位是b失配值为1此时第六位的b等于第1位的b所以f[6]=f[5]+1=2
0 1 2 3 4 5 6 7
a b c d a b d
0 0 0 0 0 1 2
同理第七位f[7]=0;
这里我们按照方法一来继续讲解
/*
* 0 1 2 3 4 5 6 7 //字符串字符对应位置
* a b c d a b d //字符串
* 0 0 0 0 0 1 2 0 //字符串的失配值
*/ /*
* 当i等于1时即字符串位置是0->0此时失配值为0因为无
* 前后缀相同同理当i等2时也一样,依次类推,当i等于
* 5时字符串对应位置为0->4(长度为5)此时f[5]=1因为
* 有相同的 前后缀a且长度为1,当i等于6时字符串对应位置
* 0->5此时f[6]=2因为有相同前后缀ab
* 这就验证了我们上边所说的
* 注意:在这里我们的前后缀不考虑整个字符串本身,而且
* 所求前后缀的子串时我们的i表示的长度
*/
因此我们想要求前后缀相同的子串的长度只需要求对应位置失配函数f[i]的值即可
这里以题目中两组数据为例:
/*
*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
*0 0 0 1 2 0 1 2 3 4 3 4 3 4 5 6 7 8 9
*f[18]=9 f[9]=4 f[4]=2 f[2]=0
*所以我们只需要每次让k=f[k],然后取 f[k]的值直到
*k等于0即可得到结果
*
*0 1 2 3 4 5
*a a a a a
*0 0 1 2 3 4
*同样f[5]=4 f[4]=3 f[3]=2 f[2]=1 f[1]=0
*/
AC代码:
#include<stdio.h>
#include<string.h>
#define MAX 400100
char str[MAX];
int f[MAX];
int dp[MAX];
int len;
void getfail()
{
int i,j;
f[0]=f[1]=0;
for(i=1;i<len;i++)
{
j=f[i];
while(j&&str[i]!=str[j])
j=f[j];
f[i+1]=str[i]==str[j]?j+1:0;
}
}
void kmp()
{
int k=len;
int n=0;
while(f[k])
{
dp[n++]=f[k];
k=f[k];
}
for(int i=n-1;i>=0;i--)
printf("%d ",dp[i]);
printf("%d\n",len);
}
int main()
{
int i;
while(scanf("%s",str)!=EOF)
{
len=strlen(str);
getfail();
kmp();
}
return 0;
}
poj 2752 Seek the Name, Seek the Fame【KMP算法分析记录】【求前后缀相同的子串的长度】的更多相关文章
- POJ-2752 Seek the Name, Seek the Fame 字符串问题 KMP算法 求前后缀串相同数木
题目链接:https://cn.vjudge.net/problem/POJ-2752 题意 给一个字符串,求前缀串跟后缀串相同的前缀串的个数 例:alala 输出:a, ala, alala 思路 ...
- POJ 3376 Finding Palindromes(manacher求前后缀回文串+trie)
题目链接:http://poj.org/problem?id=3376 题目大意:给你n个字符串,这n个字符串可以两两组合形成n*n个字符串,求这些字符串中有几个是回文串. 解题思路:思路参考了这里: ...
- Seek the Name, Seek the Fame
poj2752:http://poj.org/problem?id=2752 题意:给你一个串,让你求前n个字符和后n个字符相同的n有多少,从小到大输出来. 题解:这一题要深刻理解KMP的next数组 ...
- (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: 10204 Ac ...
- 【POJ 2752 Seek the Name, Seek the Fame】
Time Limit: 2000MSMemory Limit: 65536K Description The little cat is so famous, that many couples tr ...
随机推荐
- CSS Positioning(定位)
Positioning(定位) CSS定位属性允许你为一个元素定位.它也可以将一个元素放在另一个元素后面,并指定一个元素的内容太大时,应该发生什么. 元素可以使用的顶部,底部,左侧和右侧属性定位.然而 ...
- js实现简单计算器
效果图: 刚开始做时没考虑到清零和退格两个功能,嘻嘻,后来加的整体与传统计算器比有点小瑕疵. 代码: <!DOCTYPE html><html><head> < ...
- 用QT 还是MFC ? (转)
我曾经使用过QT和MFC来开发过软件,我想和大家分享我使用他们时所体会的不同之处. 我并非一个职业作家,这篇文章可能看起来不如专业的杂志和网站上的那么条理清晰.但是,我在这里是用我自己的语言来表达我自 ...
- grub2 使用memdisk工具 启动任意iso
root@zhanghua-Inspiron-:/home/zhanghua# df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/sda6 60G 12G 46G 21% / none ...
- bootstrap轮播组件,大屏幕图片居中效果
在慕课网学习bootstrap轮播组件的时候,了解到轮播的图片都放在了类名为item下的img中 视频中老师对图片自适应采用给图片img设置width=100%完成,然而这样自适应处理图片在不同屏幕中 ...
- jQuery源码整体结构(源码2.0.3)
拨开jQuery的面纱,最近了解了下jQuery源码整体框架.主要包括: (1) jQuery 核心模块 (2) sizzle 选择器引擎 (3) Deferred 异步队列 (4) Supp ...
- 配置nginx1.7.8支持pathinfo模式
vi nginx/conf/nginx.conf 1.修改正则 set $real_script_name $fastcgi_script_name; if ($fastcgi_script_name ...
- python入门笔记第一天
查询acsii命令 ord(‘A’) 导入模块python执行系统命令显示文件.查找文件方法1import osa = os.popen('目标').read()a 解释output = os.pop ...
- EOF
Process to end of file 就是处理到文件的结束 以经典的 A + B Problem 为例 把每一行的两个数字加起来,然后打印出来,直到文件末尾 c 语言表示:
- 2016022602 - redis安装和启动
redis安装 我使用的是ubuntu15.1,打开终端,输入命令:sudo apt-get install redis-server 将会在本机安装上redis. 启动redis 启动redis命令 ...