您的位置:首页 > 其它

hdu 1403 Longest Common Substring - 后缀数组

2013-05-07 19:48 435 查看
/*
第一次做后缀数组
就是求连个串的公共子串

简单的后缀数组

*/
#include<stdio.h>
#include<string.h>
#define MAXN 200010
char str[100000+10];
int r[100000*2+10];

int wa[MAXN], wb[MAXN], wv[MAXN], ws[MAXN];
int sa[MAXN]; //index range 1~n value range 0~n-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)//r[0  n-1]   sa[0    n-1]   最大值小于m
{
int i,j,p,*x=wa,*y=wb,*t;

for(i=0; i<m; i++)
ws[i]=0;
for(i=0; i<n; i++)
ws[x[i]=r[i]]++;//x==rank   难道是统计字符个数
for(i=1; i<m; i++)
ws[i]+=ws[i-1];//加上前一个
for(i=n-1; i>=0; i--)
sa[--ws[x[i]]]=i;//排第[i]的是谁

for(j=1,p=1; p<n; j*=2,m=p)
{
for(p=0,i=n-j; i<n; i++) //变量j是当前字符串的长度,
y[p++]=i;// 数组y保存的是对第二关键字排序的结果
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++)
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];

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;
}

int rank[MAXN]; //index range 0~n-1 value range 1~n
int height[MAXN]; //index from 1   (height[1] = 0)
void calHeight(int *r, int *sa, 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);
return;
}

int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
int i,len,n,zhong;
while(gets(str))
{
zhong=len=strlen(str);
for(n=0;n<len;++n)
{
r
=str
;
}
r[n++]=127;
gets(str);
for(i=0;str[i];++i,n++)
{
r
=str[i];
}
r
=0;
da(r,sa,n+1,128);
calHeight(r, sa, n);  //注意这儿是n啊
int ret=0;
for(i=2;i<=n;++i)
{
if((sa[i]<zhong&&sa[i-1]>zhong)||(sa[i]>zhong&&sa[i-1]<zhong))
{
ret=max(ret,height[i]);
}
}
printf("%d\n",ret);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: