Longest Common Substring

Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 37 Accepted Submission(s): 28
 
Problem Description
Given two strings, you have to tell the length of the Longest Common Substring of them.

For example:
str1 = banana
str2 = cianaic

So the Longest Common Substring is "ana", and the length is 3.

 
Input
The input contains several test cases. Each test case contains two strings, each string will have at most 100000 characters. All the characters are in lower-case.

Process to the end of file.

 
Output
For each test case, you have to tell the length of the Longest Common Substring of them.
 
Sample Input
banana
cianaic
 
Sample Output
3
 
Author
Ignatius.L
 
/*----------------------------------------------
File: F:\ACM源代码\数据结构--后缀数组\Longest_Common_Substring.cpp
Date: 2017/5/30 16:55:36
Author: LyuCheng
----------------------------------------------*/
/*
题意:最长公共子序列 思路:问题很多,DP基本不用考虑,因为时间复杂度空间复杂度都不允许,NlogN的算法也不行,最坏的情况
转化成LIS的数组是1e10空间复杂的不允许,所以只能利用后缀数组的性质,将两个连接,然后前后两个
前缀在两个不同的字符串中的时候,更新height的值,因为后缀加前缀,刚好是公共子序列
*/
#include <bits/stdc++.h>
#define MAXN 100005
using namespace std;
char s1[MAXN],s2[MAXN];
/****************************************后缀数组模板****************************************/
const int maxn=+;
struct SuffixArray
{
char s[maxn];
int sa[maxn],rank[maxn],height[maxn];
int t1[maxn],t2[maxn],c[maxn],n;
int dmin[maxn][];
void build_sa(int m)
{
int i,*x=t1,*y=t2;
for(i=;i<m;i++) c[i]=;
for(i=;i<n;i++) c[x[i]=s[i]]++;
for(i=;i<m;i++) c[i]+=c[i-];
for(i=n-;i>=;i--) sa[--c[x[i]]]=i;
for(int k=;k<=n;k<<=)
{
int p=;
for(i=n-k;i<n;i++) y[p++]=i;
for(i=;i<n;i++)if(sa[i]>=k) y[p++]=sa[i]-k;
for(i=;i<m;i++) c[i]=;
for(i=;i<n;i++) c[x[y[i]]]++;
for(i=;i<m;i++) c[i]+=c[i-];
for(i=n-;i>=;i--) sa[--c[x[y[i]]]] = y[i];
swap(x,y);
p=,x[sa[]]=;
for(i=;i<n;i++)
x[sa[i]]= y[sa[i]]==y[sa[i-]]&&y[sa[i]+k]==y[sa[i-]+k]? p-:p++;
if(p>=n) break;
m=p;
}
}
void build_height()//n不能等于1,否则出BUG
{
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(s[i+k]==s[j+k])k++;
height[rank[i]]=k;
}
}
void initMin()
{
for(int i=;i<=n;i++) dmin[i][]=height[i];
for(int j=;(<<j)<=n;j++)
for(int i=;i+(<<j)-<=n;i++)
dmin[i][j]=min(dmin[i][j-] , dmin[i+(<<(j-))][j-]);
}
int RMQ(int L,int R)//取得范围最小值
{
int k=;
while((<<(k+))<=R-L+)k++;
return min(dmin[L][k] , dmin[R-(<<k)+][k]);
}
int LCP(int i,int j)//求后缀i和j的LCP最长公共前缀
{
int L=rank[i],R=rank[j];
if(L>R) swap(L,R);
L++;//注意这里
return RMQ(L,R);
}
}sa;
/****************************************后缀数组模板****************************************/ int main(){
// freopen("in.txt","r",stdin);
while(scanf("%s%s",s1,s2)!=EOF){
int n=strlen(s1);
int m=strlen(s2);
for(int i=;i<n;i++){
sa.s[i]=s1[i];
}
sa.s[n]='$';
for(int i=n;i<n+m;i++){
sa.s[i]=s2[i-n];
}
sa.n=m+n+;
sa.build_sa(MAXN);
sa.build_height();
int maxLCS=-;
for(int i=;i<m+n+;i++){
if(i==){
maxLCS=max(maxLCS,sa.height[i]);
}else{
if((sa.sa[i]-n)*(sa.sa[i-]-n)<)//保证两后缀是来自不同的字符串的
maxLCS=max(maxLCS,sa.height[i]);
}
}
printf("%d\n",maxLCS);
}
return ;
}

Longest Common Substring(最长公共子序列)的更多相关文章

  1. lintcode 77.Longest Common Subsequence(最长公共子序列)、79. Longest Common Substring(最长公共子串)

    Longest Common Subsequence最长公共子序列: 每个dp位置表示的是第i.j个字母的最长公共子序列 class Solution { public: int findLength ...

  2. LCS(Longest Common Subsequence 最长公共子序列)

    最长公共子序列 英文缩写为LCS(Longest Common Subsequence).其定义是,一个序列 S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则 S 称为已 ...

  3. LCS修改版(Longest Common Subsequence 最长公共子序列)

    题目描述 作为一名情报局特工,Nova君(2号)有着特殊的传达情报的技巧.为了避免被窃取情报,每次传达时,他都会发出两句旁人看来意义不明话,实际上暗号已经暗含其中.解密的方法很简单,分别从两句话里删掉 ...

  4. hdu 1403 Longest Common Substring(最长公共子字符串)(后缀数组)

    http://acm.hdu.edu.cn/showproblem.php?pid=1403 Longest Common Substring Time Limit: 8000/4000 MS (Ja ...

  5. LCS(Longest Common Subsequence)最长公共子序列

    最长公共子序列(LCS)是一个在一个序列集合中(通常为两个序列)用来查找所有序列中最长子序列的问题.这与查找最长公共子串的问题不同的地方是:子序列不需要在原序列中占用连续的位置 .最长公共子序列问题是 ...

  6. C++版 - Lintcode 77-Longest Common Subsequence最长公共子序列(LCS) - 题解

    版权声明:本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C++版 - L ...

  7. POJ 1458 Common Subsequence(最长公共子序列LCS)

    POJ1458 Common Subsequence(最长公共子序列LCS) http://poj.org/problem?id=1458 题意: 给你两个字符串, 要你求出两个字符串的最长公共子序列 ...

  8. HDU 1159 Common Subsequence 最长公共子序列

    HDU 1159 Common Subsequence 最长公共子序列 题意 给你两个字符串,求出这两个字符串的最长公共子序列,这里的子序列不一定是连续的,只要满足前后关系就可以. 解题思路 这个当然 ...

  9. Common Subsequence--poj1458(最长公共子序列)

    Common Subsequence Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 43211   Accepted: 17 ...

  10. UVA10100:Longest Match(最长公共子序列)&&HDU1458Common Subsequence ( LCS)

    题目链接:http://blog.csdn.net/u014361775/article/details/42873875 题目解析: 给定两行字符串序列,输出它们之间最大公共子单词的个数 对于给的两 ...

随机推荐

  1. 基于pytorch实现HighWay Networks之Train Deep Networks

    (一)Highway Networks 与 Deep Networks 的关系 理论实践表明神经网络的深度是至关重要的,深层神经网络在很多方面都已经取得了很好的效果,例如,在1000-class Im ...

  2. 比较JqGrid与XtraGrid

    此只能比较两者的功能优劣,实现某种功能.效果的方便性和效率.首先分别粗略介绍XtraGrid和jqGrid DevExpress是目前.net下最为强大和完整的UI控件库, XtraGrid是这个控件 ...

  3. java 对象转型

    一.对象转型介绍 对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型.转型的意思是:如把float类型转成int类型,把double类 ...

  4. 我是如何利用Hadoop做大规模日志压缩的

    背景 刚毕业那几年有幸进入了当时非常热门的某社交网站,在数据平台部从事大数据开发相关的工作.从日志收集.存储.数据仓库建设.数据统计.数据展示都接触了一遍,比较早的赶上了大数据热这波浪潮.虽然今天的人 ...

  5. vue路由跳转 vue-router的使用

    1.路由对象和路由匹配 路由对象,即$router会被注入每个组件中,可以利用它进行一些信息的获取.如 属性 说明 $route.path 当前路由对象的路径,如'/view/a' $rotue.pa ...

  6. 1.Bootstrap-简介

    1.介绍 Bootstrap 是一个用于快速开发 Web 应用程序和网站的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的. 2.HTML 模板 一个使用了 Boots ...

  7. M方法

    ThinkPHP函数详解:M方法 M方法用于实例化一个基础模型类,和D方法的区别在于:1.不需要自定义模型类,减少IO加载,性能较好:2.实例化后只能调用基础模型类(默认是Model类)中的方法:3. ...

  8. QT的安装及环境配置

    QT的安装及环境配置 一.windows的下QT的安装及环境配置 (一)从框架安装程序中安装 步骤: 准备:下载QT库,下载指定版本的MINGW,QT IDE 1.下载QT安装文件如:qt-win-o ...

  9. C语言编程练习(一)

    问题一: 问题描述:输入n个数,n<=100,找到其中最小的数和最大的数 输入样例: 4                      1 2 3 4 输出样例:14 #include " ...

  10. The Nerd Factor SPOJ - MYQ5

    The Nerd Factor Time Limit: 1000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu [Submi ...