HDU1403 Longest Common Substring
2014-07-09 14:02
302 查看
Longest Common Substring
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3851 Accepted Submission(s): 1443
[align=left]Problem Description[/align]
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.
[align=left]Input[/align]
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.
[align=left]Output[/align]
For each test case, you have to tell the length of the Longest Common Substring of them.
[align=left]Sample Input[/align]
banana cianaic
[align=left]Sample Output[/align]
3
[align=left]Author[/align]
Ignatius.L
后缀数组的模板题。。。代码加了注释
#include<cstdio> #include<cstring> using namespace std; const int MAXN=1000010; int wa[MAXN],wb[MAXN],wv[MAXN],ws[MAXN]; int sa[MAXN],r[MAXN<<1]; 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; //对长度为1的字符串排序 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++) //统计不大于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里保存的是第二关键字的排序结果,结合图后j很弱字符串的第二关键都是0 y[p++]=i; for(i=0;i<n;i++) //第二关键字的排序可以直接根据第一次排序的sa来看 if(sa[i]>=j) //sa里存的是排名第i的是谁 y[p++]=sa[i]-j; for(i=0;i<n;i++) //x保存了rank的值,用y又是运用了第二关键字排序的结果,也是基数排序的要求 wv[i]=x[y[i]]; //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]; //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++;//rank值相同位置也要相同 } return; } int rank[MAXN],height[MAXN]; void callheight(int *r,int *sa,int n) { int i,j,k=0; for (i=1;i<=n;++i) //rank里记录的是排名 rank[sa[i]]=i; for (i=0;i<n;height[rank[i++]]=k) for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];++k); //那个结论height[rank[i]]>=height[rank[i-1]]-1 return; //k==0不动,不为0就要减一 } char s[MAXN<<1]; int main() { int i; while(scanf("%s",s)!=EOF) { int len=strlen(s); s[len]='0'; //要将两个串合成一条串,然后求他子串的最长公共前缀就行 int len1=len; scanf("%s",s+1+len); len=strlen(s); for(i=0;i<len;i++) r[i]=s[i]; r[len]=0; da(r,sa,len+1,300); callheight(r,sa,len); int ans=0; for(i=2;i<=len;i++) { if(ans<height[i]) { if((sa[i]>len1&&sa[i-1]<len1)||(sa[i]<len1&&sa[i-1]>len1)) //sa记录的是排名第几的是谁 ans=height[i]; } } printf("%d\n",ans); } return 0; }
相关文章推荐
- 【HDU】1403 Longest Common Substring
- hdu1403 Longest Common Substring
- HDU 1403 Longest Common Substring
- hdu 1403 Longest Common Substring 后缀数组求最长公共子串
- POJ 2774 Long Long Message&&HDU 1403 Longest Common Substring&&COJ 1203
- hdu 1403 Longest Common Substring 后缀数组求最长公共子串
- HDU 1403 Longest Common Substring(后缀数组,最长公共子串)
- hdu 1403 Longest Common Substring - 后缀数组
- hdu 1403 Longest Common Substring (后缀数组)
- HDU - 1403 Longest Common Substring
- hdu_1403_Longest Common Substring(后缀数组的应用)
- 【hdu 1403】Longest Common Substring
- hdu 1403 Longest Common Substring (后缀数组模板)
- HDU - 1403 - Longest Common Substring
- poj2774 Long Long Message && hdu 1403 Longest Common Substring 最长公共字串【后缀数组(倍增)】
- HDU 1403 Longest Common Substring(后缀数组 最长公共子串)
- hdu-1403-Longest Common Substring
- hdu1403---Longest Common Substring(后缀数组求2个字符串的最长公共子串)
- HDU 1403 Longest Common Substring
- HDU 1403 Longest Common Substring(最长公共子串)