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 ...
随机推荐
- 网页解析Jsoup简单使用
public static void main(String[] args) throws IOException { //System.out.println("Hello World!& ...
- line-height行高使用技巧
若父元素标签高度一定,假设为150px,子元素需要垂直居中,再重新给子元素设置一个行高就好了,省事省力
- JavaScript学习总结【8】、面向对象编程
1.什么是面向对象编程 要理解面向对象,得先搞清楚什么是对象,首先需要明确一点这里所说的对象,不是生活中的搞男女朋友对象,面向对象就是面向着对象,换在代码中,就是一段代码相中了另一段代码,自此夜以继日 ...
- 《JavaScript高级程序设计 第3版》-学习笔记-2
P31-P82页 1.相等不相等与全等不全等 相等不相等:先转换后比较.对于只有一个对象,调用valueOf方法得到基本类型值再按基本类型转换:如果两个都是对象,则比较他们是否是同一个对象(引用或指针 ...
- ERROR 2003 (HY000): Can't connect to MySQL server
http://blog.csdn.net/longxibendi/article/details/6363934 一.问题的提出 /usr/local/webserver/mysql/bin/mysq ...
- 用三或四个个div标签实现工字效果
使用重构的方式制作出一个如下图的水平.垂直都居中,短边为50px,长边为150px的红色“工”字. a) 使用3个div完成 <!DOCTYPE html><html lang=&q ...
- Junit4 架构设计系列(2): Runner.run()与Statement
Overall 系列入口: Junit4 架构设计系列(1): Request,ClassRequest 和 RunnerBuilder 前文中,我们基本理清了Junit4执行Case大体上的Flow ...
- PHP 7.0 安装使用与性能监测!
PHP 7.0发布,网上关于新版的介绍很多,介于 7.0 在正式发布之前已经发过若干个 Beta.8个 RC,应该不会出现重大问题.今日我将一台机器升级至 PHP 7.0 并将有关信息记录如下. 本人 ...
- C++中结构体与类的区别(结构不能被继承,默认是public,在堆栈中创建,是值类型,而类是引用类型)good
结构是一种用关键字struct声明的自定义数据类型.与类相似,也可以包含构造函数,常数,字段,方法,属性,索引器,运算符和嵌套类型等,不过,结构是值类型. 1.结构的构造函数和类的构造函数不同. a. ...
- QT获得所有系统环境变量(包括Linux和MAC的信息)
系统环境变量还是挺重要的,除了QStandardPaths(感觉都是文档类型的变量,QT4使用QDesktopServices),更有QProcessEnvironment(都是真正的系统变量): Q ...