标签:
Time Limit: 4000MS | Memory Limit: 131072K | |
Total Submissions: 23163 | Accepted: 9509 | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit yeaphowmuchiloveyoumydearmother
Sample Output
27
Source
/** 题意:求两个字符串的最长公共子串 做法:后缀数组 求两个串的最长公共子串等价于求两个串的最长公共前缀的最大值 所以把两个字符串合并成一个字符串并且对其进行da(); sa[]数组 表示排第几的是谁 Rank[] 表示谁排第几 heigth[] 表示suffix(sa[i])和suffix(sa[i-])之间的公共前缀的个数 **/ #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <cmath> #include <queue> #define maxn 220010 // 100000. int t1[maxn],t2[maxn],c[maxn]; int sa[maxn],height[maxn],rank[maxn]; int a[maxn],b[maxn]; using namespace std; bool cmp(int *r,int a,int b,int l) { return r[a] == r[b] &&r[a+l] == r[b+l]; } void da(int str[],int sa[],int rank[],int heigth[],int n,int m) { n++; ///桶式排序 int i,j,p,*x = t1,*y = t2; for(i=0; i<m; i++) c[i] = 0; ///初始化 for(i=0; i<n; i++) c[x[i] = str[i]] ++;///每个字符串出现的次数 for(i=1; i<m; i++) c[i] += c[i-1]; ///字符串中各个字符的个数 for(i=n-1; i>=0; i--) sa[--c[x[i]]] = i; ///下一轮的第二关键字 for(j=1; j<=n; j<<=1) { p=0; for(i=n-j; i<n; i++) y[p++] = i; ///n-j 因为每次排序都是对字符串开始的长度为2^k的字符串进行排序的 /// 所以n-j是拍不到的部分 并且是对第二关键字的排序 for(i=0; i<n; i++) if(sa[i] >= j) y[p++] = sa[i]-j; ///只有满足sa[i] >= j 才能作为y数组的第二关键字存储第一关键字 for(i=0; i<m; i++) c[i] = 0; for(i=0; i<n; i++) c[x[y[i]]]++; for(i=1; i<m; i++) c[i] += c[i-1]; for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i]; swap(x,y); p=1; x[sa[0]] = 0; for(i=1; i<n; i++) x[sa[i]] = cmp(y,sa[i-1],sa[i],j) ?p-1:p++; if(p >= n) break; m = p; } int k=0; n--; for(i=0; i<=n; i++) rank[sa[i]] = i; for(i=0; i<n; i++) { if(k) k--; j = sa[rank[i]-1]; while(str[i+k] == str[k+j]) k++; heigth[rank[i]] = k; } } char str[maxn]; char str1[maxn]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif // ONLINE_JUDGE while(~scanf("%s",str)) { // cout<<str<<endl; scanf("%s",str1); int len = strlen(str); int n =0; for(int i=0; i<len; i++) { a[n++] = str[i] -‘a‘+1; } a[n++] = 28; len = strlen(str1); for(int i=0; i<len; i++) { a[n++] = str1[i] - ‘a‘+1; } da(a,sa,rank,height,n,30); int maxx=0,pos=0; len=strlen(str); for(int i=2; i<n; i++) if(height[i]>maxx) { if(0<=sa[i-1]&&sa[i-1]<len&&len<sa[i]) maxx=height[i]; if(0<=sa[i]&&sa[i]<len&&len<sa[i-1]) maxx=height[i]; } printf("%d\n",maxx); } }
标签:
原文地址:http://www.cnblogs.com/chenyang920/p/4571429.html