poj 2774 求两个字符串的最长公共子串

来源:互联网 发布:学生空间七天网络查分 编辑:程序博客网 时间:2024/05/14 16:15
#include<stdio.h>#include<iostream>#include<string.h>#define N 200005using namespace std;char str[N];int s[N],t1[N],t2[N],c[N],sa[N],height[N],ran[N];void build_sa(int *s,int n,int m){    int *x=t1,*y=t2,p,i,k;    for(i=0;i<m;i++) c[i]=0;    for(i=0;i<n;i++) c[x[i]=s[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(k=1;k<=n;k<<=1)    {       p=0;       for(i=n-k;i<n;i++)  y[p++]=i;       for(i=0;i<n;i++) if(sa[i]>=k)  y[p++]=sa[i]-k;       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];       p=1;  swap(x,y);  x[sa[0]]=0;       for(i=1;i<n;i++)        x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+k]==y[sa[i]+k] ? p-1:p++;      if(p>=n)        break;     m=p;    }}void getheight(int n){ int i,j,k=0;  for(i=0;i<n;i++)    ran[sa[i]]=i;  for(i=0;i<n;i++)  {    if(k) k--;    j=sa[ran[i]-1];    while(s[i+k]==s[j+k]) k++;    height[ran[i]]=k;  }}int main(){  int n,m,i,max;  while(scanf("%s",str)!=EOF)  {    n=strlen(str);    str[n]='$';    scanf("%s",str+n+1);    m=strlen(str);    for(i=0;i<m;i++)      s[i]=str[i];    build_sa(s,m,130);    getheight(m);    max=-1;    for(i=1;i<m;i++)    {      if((sa[i]<n&&sa[i-1]>n||(sa[i]>n&&sa[i-1]<n))&&height[i]>max)         max=height[i];    }    printf("%d\n",max);  }  return 0;}

0 0
原创粉丝点击