题目链接:点击打开题目链接
Longest Common Substring
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5417 Accepted Submission(s): 1923
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.
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.
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
题意:给两个字符串,求最长公共子串的长度
方法:
将它们合并为一个串,然后利用后缀数组求解;先输入一个串s,长度len1,再输入第二个串scanf("%s,s+len1),这样就把两个串合并到了一起,这时长度len,把字符型数组s转换为整型数组r,再加一个r[len]=0;这时候再套用后缀数组的模板,求出height[i]的最大值,但是要保证相邻的两个子串的sa分别属于原来输入的两个串,即要满足sa[i-1]<=len1 && sa[i]>len1或者sa[i]<=len1&&sa[i-1]>len1;
贴AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
int wa[200005],wb[200005],wv[200005],ws[200005];
int r[200005],height[200005],rank1[200005],sa[200005];char s[200005];
int cmp(int *r,int a,int b,int l){
return r[a]==r[b]&&r[a+l]==r[b+l];
}
void da(int *r,int *sa,int n,int m){
int i,j,p,*x=wa,*y=wb,*t;
for(i=0;i<m;i++) ws[i]=0;
for(i=0;i<n;i++) ws[x[i]=r[i]]++;
for(i=1;i<m;i++) ws[i]+=ws[i-1];
for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;
for(j=1,p=1;p<n;j*=2,m=p){
for(p=0,i=n-j;i<n;i++) y[p++]=i;
for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
for(i=0;i<n;i++) wv[i]=x[y[i]];
for(i=0;i<m;i++) ws[i]=0;
for(i=0;i<n;i++) ws[wv[i]]++;
for(i=1;i<m;i++) ws[i]+=ws[i-1];
for(i=n-1;i>=0;i--) sa[--ws[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
}
return;
}
void calheight(int *r,int *sa,int n){
int i,j,k=0;
for(i=1;i<=n;i++) rank1[sa[i]]=i;
for(i=0;i<n;height[rank1[i++]]=k)
for(k?k--:0,j=sa[rank1[i]-1];r[i+k]==r[j+k];k++);
return;
}
int main()
{
int i;
while(scanf("%s",s)!=EOF)
{
int len=strlen(s),len1=strlen(s);
scanf("%s",s+len);
len=strlen(s);
for(i=0;i<len;i++)
r[i]=s[i];
r[len]=0;
da(r,sa,len+1,300);
calheight(r,sa,len);
int max=0;
for(i=1;i<=len;i++)
{
if(height[i]>max)
{
if(sa[i-1]<len1&&sa[i]>=len1||sa[i-1]>=len1&&sa[i]<len1)
max=height[i];
}
}
printf("%d\n",max);
}
}