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 ...
随机推荐
- jQuery 尺寸
通过 jQuery,很容易处理元素和浏览器窗口的尺寸. jQuery 尺寸 方法 jQuery 提供多个处理尺寸的重要方法: width() height() innerWidth() innerHe ...
- pc110301QWERTYU
水题一道,SOLVED只是次数的问题.map一下,就是很easy啦. #include<iostream> #include<cstdio> #include<cstri ...
- View.setTag()的作用
//这个东西在一些需要用到Adapter自定控件显示方式的时候非常有用 //Adapter 有个getView方法,可以使用setTag把查找的view缓存起来方便多次重用 public View g ...
- 百度劫持js代码
js代码为: var myDate=new Date(); //返回一日期对象,可以调用getDate(),内容为当前时间,这句是新建一个对象d建好对象后d就有函数date()中的所有特性 var h ...
- AngularJS初体验
最近突然发现,Coding.net真是一个神奇的网站.这各网站90%的请求都是通过ajax完成的.可以发现,不管你点任何链接,网页都不会刷新,点击浏览器的返回或前进按钮也是这样,打开chrome的开发 ...
- C#中获得汉字的首拼音(简化版)
利用汉字在计算机里面的编码来得到汉字的首拼音: static public string GetChineseSpell(string strText) { int len = strText.Len ...
- Java实现http服务器(一)
基于Java实现Http服务器有多种多样的方法 一种轻量级的方式是使用JDK内置的com.sun.net.httpserver包下和sun.net.httpserver包下类提供的方法构建,该方法轻便 ...
- 抓取天涯文章的蜘蛛代码,刚经过更新(因为天涯页面HTML代码变化)
#_*_coding:utf-8-*- import urllib2 import traceback import codecs from BeautifulSoup import Beautifu ...
- android小知识
string 与 []byte 互转: public String BytesToString(byte[] data) { return new String(data); } public byt ...
- bzoj 3143: [Hnoi2013]游走 高斯消元
3143: [Hnoi2013]游走 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1026 Solved: 448[Submit][Status] ...