poj2774 Long Long Message 后缀数组求最长公共子串
题目链接:http://poj.org/problem?id=2774
这是一道很好的后缀数组的入门题目
题意:给你两个字符串,然后求这两个的字符串的最长连续的公共子串
一般用后缀数组解决的两个字符串的问题都通过将一个字符串加在另一个字符串的后面来解决
我们知道对于任意一个子串都是当前字符串的某一个后缀的前缀
预处理时,假设当前输入的两个字符串为s,p;我们将p加在s的h后面
那么求这两个字符串的最长公共子串,就转化为求某两个后缀的最长公共前缀
我们知道任意两个后缀的最长公共前缀一定是height数组中的某一个值
(对于sa[i]和sa[j] ,他们的最长公共前缀就是minheight[k](i<k<j);
那么答案是否就是height数组的最大值呢,答案是否定的,因为可能出现排名相邻的后缀来自于同一个子串
那么答案就很明显了。就是排名相邻的除去两个后缀都来自于相同字符串的height的最大值
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define maxn 1000001
int wa[maxn*+],wb[maxn*+],wv[maxn*+],wq[maxn*+];
int rank[maxn*+],sa[maxn*+];
int r[maxn*+];
int height[maxn*+];
char s[maxn],p[maxn];
int len1,len2,n;
int cmp(int *r,int a,int b,int l)
{return r[a]==r[b]&& r[a+l]==r[b+l];}
void da(int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=;i<m;i++) wq[i]=;
for(i=;i<n;i++) wq[x[i]=r[i]]++;
for(i=;i<m;i++) wq[i]+=wq[i-];
for(i=n-;i>=;i--) sa[--wq[x[i]]]=i; for(j=,p=;p<n;j*=,m=p)
{
for(p=,i=n-j;i<n;i++) y[p++]=i;
for(i=;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=;i<n;i++) wv[i]=x[y[i]];
for(i=;i<m;i++) wq[i]=;
for(i=;i<n;i++) wq[wv[i]]++;
for(i=;i<m;i++) wq[i]+=wq[i-];
for(i=n-;i>=;i--) sa[--wq[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
return ;
}
void callheight(int n)
{
int i,j,k=;
for(i=;i<=n;i++) rank[sa[i]]=i;
for(i=;i<n;i++)
{
if(k) k--;
j=sa[rank[i]-];
while(r[i+k]==r[j+k]) k++;
height[rank[i]]=k;
}
}
int main()
{
while(scanf("%s%s",s,p)!=EOF)
{
int len1=strlen(s);
int len2=strlen(p);
s[len1]='$';
strcat(s,p);
n=strlen(s);
for(int i=;i<n;i++)
r[i]=s[i];
r[n]=;
da(n+,*maxn+);
callheight(n);
int ans=;
for(int i=;i<=n;i++)
{
if((sa[i]<len1 && sa[i-]>len1)||(sa[i]>len1&&sa[i-]<len1))
ans=max(ans,height[i]);
}
cout<<ans<<endl; }
return ; }
poj2774 Long Long Message 后缀数组求最长公共子串的更多相关文章
- Long Long Message (poj2774 后缀数组求最长公共子串)
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 19206 Accepted: 79 ...
- poj2774 后缀数组 求最长公共子串
Reference:IOI2009论文 http://www.cnblogs.com/ziyi--caolu/p/3192731.html #include "stdio.h" # ...
- HDU 1403 Longest Common Substring(后缀数组,最长公共子串)
hdu题目 poj题目 参考了 罗穗骞的论文<后缀数组——处理字符串的有力工具> 题意:求两个序列的最长公共子串 思路:后缀数组经典题目之一(模版题) //后缀数组sa:将s的n个后缀从小 ...
- poj 2774 Long Long Message,后缀数组,求最长公共子串 hdu1403
题意:给出两个字符串,求最长公共子串的长度. 题解:首先将两个字符串连在一起,并在中间加一个特殊字符(字串中不存在的)切割,然后两个串的最长公共字串就变成了全部后缀的最长公共前缀.这时就要用到heig ...
- POJ 2774 Long Long Message (二分 + Hash 求最长公共子串)题解
题意:求最长公共子串 思路:把两个串Hash,然后我们把短的作为LCS的最大可能值,然后二分长度,每次判断这样二分可不可以.判断时,先拿出第一个母串所有len长的子串,排序,然后枚举第二个母串len长 ...
- 求最长公共子串 Longest Common Subsequence
最长公共子串 // Longest Common Subsequence 子串有别于子序列, 子串是连续的, 而子序列可以不连续 /*--------------------------------- ...
- 文本比较算法Ⅱ——Needleman/Wunsch算法的C++实现【求最长公共子串(不需要连续)】
算法见:http://www.cnblogs.com/grenet/archive/2010/06/03/1750454.html 求最长公共子串(不需要连续) #include <stdio. ...
- POJ2774 Long Long Message —— 后缀数组 两字符串的最长公共子串
题目链接:https://vjudge.net/problem/POJ-2774 Long Long Message Time Limit: 4000MS Memory Limit: 131072 ...
- 后缀数组(模板题) - 求最长公共子串 - poj 2774 Long Long Message
Language: Default Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 21 ...
随机推荐
- 爱回收jd图标
http://jd.aihuishou.com/images/icons.png http://misc.360buyimg.com/201007/skin/df/i/bg_hotsale.gif 来 ...
- php写留言板
简单的PHP留言板制作 做基础的留言板功能 需要三张表: 员工表,留言表,好友表 首先造一个登入页面: <form action="drcl.php" method=&qu ...
- C# 索引同时含有数字和字符串的集合 同时具备IList和IDictionary的特点
同时具备IList和IDictionary的特点的集合 [Serializable] public class MyCollection:IList { private readonly Dictio ...
- keystone无法查看catalog并且用户无法申请令牌的解决方案
在运行openstack catalog list之后提示: Only an authorized user may issue a new token. #只有授权用户才能申请token opens ...
- 【C语言】浅谈可变参数与printf函数
一.何谓可变参数 int printf( const char* format, ...); 这是使用过C语言的人所再熟悉不过的printf函数原型,它的参数中就有固定参数format和可变参数(用& ...
- rsync+inotify实现文件同步更新(配置)
linux下为了数据安全或者网站同步镜像,不得不考虑一些实时备份的问题,这篇linux下通过rsync+inotify 实现数据实时备份配置过程记录下来,防止遗忘配置过程记录下来,防止遗忘!如有建议技 ...
- Xshell连接本地 Virtualbo Ubuntu
1.打开Virtualbox软件,启动ubuntu虚拟机. Ctrl + Alt + T 打开终端输入一下命令: sudo apt-get update 然后安装ssh 输入:sudo apt-get ...
- 老李分享:接口测试之jmeter
老李分享:接口测试之jmeter poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.移动端自动化测试很多人把他仅仅理解成appu ...
- JSP/Servlet------------------------->>动态网页开发基础(一)
动态网页:是指在服务器端运行的,使用程序语言设计的交互式网页,它们会根据某种条件的变化,返回不同的网页内容. 动态网站可以实现交互功能,如用户注册.信息发布.产品展示.订单管理等等: 动态网页并不是独 ...
- Linux SvN操作
Linux svn管理工具的12个命令实践 2010-08-25 10:50 佚名 icycling.cublog.cn 字号:T | T 目前,绝大多数开源软件都使用svn作为代码版本管理软件.本文 ...