aba 回文练习 -- 参考罗大神的

来源:互联网 发布:手机超星怎么看网络课 编辑:程序博客网 时间:2024/05/18 20:36
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define maxn 1024
#define parr(arr,n) printf(#arr":");for(int kk=0;kk<n;kk++) printf("%d ",arr[kk]);puts("")


int bufa[maxn],bufb[maxn],bufs[maxn],bufv[maxn];
int sa[maxn],rank[maxn],height[maxn];


int cmp(int* src,int a,int b,int l){
return src[a]==src[b]&&src[a+l]==src[b+l];
}
void da(int *src,int sz,int m)
{
int i;
int *x=bufa,*y=bufb,*t;
for(i=0;i<m;i++)     bufs[i]=0;
for(i=0;i<sz;i++)    bufs[x[i]=src[i]]++;
for(i=1;i<m;i++)    bufs[i]+=bufs[i-1];
for(i=sz-1;i>=0;--i) sa[--bufs[src[i]]]=i;


int p,j;
for(j=1,p=1;p<sz;j*=2,m=p)
{
for(p=0,i=sz-j;i<sz;i++) y[p++]=i;
for(i=0;i<sz;i++) if(sa[i]>=j) y[p++]=sa[i]-j;

for(i=0;i<sz;i++) bufv[i]=x[y[i]];
for(i=0;i<m;i++)bufs[i]=0;
for(i=0;i<sz;i++)   bufs[bufv[i]]++;
for(i=1;i<m;i++)bufs[i]+=bufs[i-1];
for(i=sz-1;i>=0;--i) sa[--bufs[bufv[i]]]=y[i];


for(t=x,x=y,y=t,p=1,i=1,x[sa[0]]=0;i<sz;++i)
 x[sa[i]]=cmp(y,sa[i],sa[i-1],j)?p-1:p++;
}
}


void cal_height(int *src, int sz)
{
int i,k,j;
for(i=1;i<sz;++i) rank[sa[i]]=i;
for(k=0,i=0;i<sz;height[rank[i++]]=k)
 for(k?k--:0,j=sa[rank[i]-1];src[i+k]==src[j+k];k++)
;
}


int RMQ[maxn],mm[maxn];
int best[20][maxn];


void initRMQ(int n)
{
int i,j;
for(mm[0]=-1,i=1;i<n;i++)
 mm[i]=(i&(i-1))==0 ? mm[i-1]+1:mm[i-1];
for(i=1;i<n;i++) best[0][i]=i; //i=1
int a,b;
for(i=1;i<=mm[n];i++)
 for(j=1;j<n-(1<<i)+1;j++){ //j=1
a=best[i-1][j];
b=best[i-1][j+(1<<(i-1))];
best[i][j]=RMQ[a]<RMQ[b] ? a:b;
 }
}


int askRMQ(int a,int b)
{
int t;
t=mm[b-a+1];
b-=((1<<t)-1);
a=best[t][a];
b=best[t][b];
return RMQ[a]<RMQ[b] ? a:b;
}


int lcp(int a,int b)
{
a=rank[a];
b=rank[b];
if(a>b) {int t=a;a=b;b=t;}
return height[askRMQ(a+1,b)];
}


int main()
{
char src[maxn],c;
int dsrc[maxn],i,len,n;
bzero(src,sizeof(src));
i=0;
while((c=getchar())!='\n') src[i++]=c;
if(c!='\n') while(getchar()!='\n');
len=strlen(src);
for(i=0;i<len;i++) dsrc[i]=src[i];
dsrc[i++]=1;
n=2*len+1;
for(;i<n;i++) dsrc[i]=src[n-i-1];      //abc -- > abc1cba
dsrc[n++]=0;


printf("n=%d\n",n);
parr(dsrc,n);
da(dsrc,n,128);
parr(sa,n);
cal_height(dsrc,n);


for(i=0;i<n;i++) RMQ[i]=height[i];
initRMQ(n);


parr(height,n);
parr(rank,n);


n--;
int ans=0,w,k;
for(i=0;i<len;i++){
k=lcp(i,n-i);
if(2*k>ans) ans=2*k,w=i-k;
k=lcp(i,n-i-1);
if(2*k-1>ans) ans=2*k-1,w=i-k+1;
}
src[w+ans]=0;
printf("%s\n",src+w);
}
原创粉丝点击