ProblemDescription
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 containsseveral test cases. Each test case contains two strings, each string will haveat most 100000 characters. All the characters are in lower-case.
Process to the end of file.
Output
For each testcase, you have to tell the length of the Longest Common Substring of them.
Sample Input
banana
cianaic
Sample Output
3
题目大意:给两段字符串,求出两段字符串最长公共子串的长度。
方法:将两个字符串连接起来。用后缀数组求出height值。根据再根据sa值判断具有公共前缀的后缀是否是同一字符串的。找出不是的height值最大的即可
//#include <iostream> //#include<cstdio> //#include<cstring> //#include<cstdlib> //#include<algorithm> //#define MAX 101000 //using namespace std; // //int n ,num[MAX] ,min1 ,cnt ,location[MAX]; //int vis[MAX]; // //int wa[MAX] ,wb[MAX] ,wv[MAX] ,ws1[MAX] ,sa[MAX] ,rank1[MAX],height[MAX]; // //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++) ws1[i]=0; // for(i=0;i<n;i++) ws1[x[i]=r[i]]++; // for(i=1;i<m;i++) ws1[i]+=ws1[i-1]; // for(i=n-1;i>=0;i--) sa[--ws1[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++) ws1[i]=0; // for(i=0;i<n;i++) ws1[wv[i]]++; // for(i=1;i<m;i++) ws1[i]+=ws1[i-1]; // for(i=n-1;i>=0;i--) sa[--ws1[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; //} // //bool jian(int x ,bool flag) //{ // int Count = 0; // memset(vis,0,sizeof(vis)); // for(int i = 1;i <= cnt;i++) // { // if(height[i] < x) // { // Count = 0; // memset(vis,0,sizeof(vis)); // continue; // } // if(!vis[location[sa[i-1]]]) // { // vis[location[sa[i-1]]] = 1; // Count++; // } // if(!vis[location[sa[i]]]) // { // vis[location[sa[i]]] = 1; // Count++; // } // if(Count > n / 2) // { // if(!flag) // { // return 1; // } // else // { // for(int j = 0;j < x;j++) // { // printf("%c",num[sa[i]+j]+'a'-1); // } // printf("\n"); // for(;i<=cnt;i++) // { // if(height[i] < x) // { // Count = 0; // memset(vis,0,sizeof(vis)); // break; // } // } // } // } // } // return 0; //} // //int main() //{ // char ch[1010]; // int len ,re; // while(scanf("%d",&n),n) // { // min1 = 99999999; // cnt = 0; // re = 27; // for(int i = 0;i<n;i++) // { // scanf("%s",ch); // len = strlen(ch); // if(len < min1) // { // min1 = len; // } // for(int j = 0;j<len;j++) // { // num[cnt] = ch[j] - 'a' + 1; // location[cnt++] = i; // } // num[cnt] = re; // location[cnt++] = re++; // } // num[cnt] = 0; // da(num,sa,cnt+1,re); // calheight(num,sa,cnt); // // int left = 0 ,right = min1 ,ans; // while(left<=right) // { // int mid = (left + right) / 2; // if(jian(mid,0)) // { // left = mid + 1; // ans = mid; // } // else // { // right = mid - 1; // } // } // if(!ans) // { // printf("?\n\n"); // } // else // { // jian(ans,1); // printf("\n"); // } // } // return 0; //} #include <iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<string> #include<algorithm> #define MAX 100010 using namespace std; char str[2*MAX]; int wa[2*MAX] ,wb[2*MAX] ,wv[2*MAX] ,sa[2*MAX]; int ws1[2*MAX]; int rank1[2*MAX],height[2*MAX]; int cmp(int *r,int a,int b,int l) {return r[a]==r[b]&&r[a+l]==r[b+l];} void da(char *r,int *sa,int n,int m) { int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) ws1[i]=0; for(i=0;i<n;i++) ws1[x[i]=r[i]]++; for(i=1;i<m;i++) ws1[i]+=ws1[i-1]; for(i=n-1;i>=0;i--) sa[--ws1[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++) ws1[i]=0; for(i=0;i<n;i++) ws1[wv[i]]++; for(i=1;i<m;i++) ws1[i]+=ws1[i-1]; for(i=n-1;i>=0;i--) sa[--ws1[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(char *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 len ,len1 ,max1; while(~scanf("%s",str)) { len1 = strlen(str); str[len1] = '#'; scanf("%s",str+len1+1); len = strlen(str); da(str,sa,len,270); calheight(str,sa,len-1); max1 = 0; for(int i = 0;i<len;i++) { if(max1 < height[i]) { if((sa[i]>len1 && sa[i-1]<len1)||(sa[i]<len1&&sa[i-1]>len1)) { max1 = height[i]; } } } printf("%d\n",max1); } return 0; }