给A ,B 两个串
要求两个字符串的最长公共子串长度
只需要用'$',分割一下就好了,不能用0
A$B
#include<iostream> #include<string.h> #include<cstdio> #include<cstring> #define MIN(a,b) (a)>(b)?(b):(a) #define MAX(a,b) (a)>(b)?(a):(b) #define INF 0x3f3f3f using namespace std; const int M=200010; int N,alen,blen; int str[M]; char a[M>>1],b[M>>1]; int sa[M] , rank[M] , height[M]; int wa[M] , wb[M] , wv[M] , wd[M]; 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 n , int m) { int i , j , p , *x = wa , *y = wb , *t; for (i = 0 ; i < m ; i++)wd[i] = 0; for (i = 0 ; i < n ; i++)wd[x[i]=r[i]]++; for (i = 1 ; i < m ; i++)wd[i] += wd[i-1]; for (i = n-1 ; i >= 0 ; i--) sa[--wd[x[i]]] = i; for (j = 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++)wd[i] = 0; for (i = 0 ; i < n ; i++)wd[wv[i]]++; for (i = 1 ; i < m ; i++)wd[i] += wd[i-1]; for (i = n-1 ; i >= 0 ; i--)sa[--wd[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++; } } void calheight(int *r , int n) { int i , j , k = 0; for (i = 1 ; i <= n ; i++) 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++); //若分割符为0则有可能会和B串末尾0配 导致h多加1 } int main() { int i,j; memset(str,0,sizeof(str)); scanf("%s",a); alen=strlen(a); for(i=0;i<alen;i++) str[i]=a[i]-'a'+2; //保证为正数且比'$'大 str[alen]=1; //此处'$' scanf("%s",b); blen=strlen(b); for(i=alen+1,j=0;j<blen;j++,i++) str[i]=b[j]-'a'+2; int minlen=MIN(alen,blen); int len=alen+blen; da(str,len+1,30); calheight(str,len); int ans =0; for (i =1; i <= len+1 ; i++) if ((sa[i] < alen && sa[i -1] > alen) || (sa[i] > alen && sa[i -1] < alen))//保证一个在A 一个在B if (height[i] > ans) ans = height[i]; printf("%d\n",ans); return 0; }