Chinaunix首页 | 论坛 | 博客
  • 博客访问: 198175
  • 博文数量: 67
  • 博客积分: 2970
  • 博客等级: 少校
  • 技术积分: 685
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-23 11:36
文章分类

全部博文(67)

文章存档

2012年(2)

2011年(19)

2010年(46)

我的朋友

分类: C/C++

2011-05-01 11:51:55

硬是花了3天时间才看懂罗穗骞的论文,然后在去切最简单pku2774,结果杯具了,自己手写的倍增算法不是这里出问题就是那里搞错,最后不是wa就是re,郁闷。。。拉倒换了pku3581,还行总算ac了,接下来写写菜鸟的理解:

int cmp(int *r,int a,int b,int l)
{return r[a]==r[b]&&r[a+l]==r[b+l];}
这个比较函数就是根据第一关键字和第二关键字来确定当前长度为j*2的字符串排名,r数组记录上次长度为j的排名

void da(int *r,int *sa,int n,int m)
{
     int i,j,p,*x=wa,*y=wb,*t;
     for(i=0;i     for(i=0;i     for(i=1;i     for(i=n-1;i>=0;i--) sa[--ws[x[i]]]=i;//逆向遍历是为了保证基数排序的稳定性,ws[i]=k记录排名<=i的有k个,先自减是为了保证sa数组下标从0开始
     for(j=1,p=1;p     {
       for(p=0,i=n-j;i       for(i=0;i=j) y[p++]=sa[i]-j;//sa[i]=k记录以k开始的长j的字符串排在第i位,恰好表明以k-j开始的长j*2的字符串的第二关键字的之间的相对位置
       for(i=0;i       for(i=0;i       for(i=0;i       for(i=1;i       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       x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;//名次数组x中记录后缀的真实排名
     }
     return;
}
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     for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++);
     return;
}

一系列字符串按从小到大的顺序排列,任意相邻的字符串都是从后缀开始发生改变,前缀一般保持不变,这样最长公共前缀一定存在于排名连续的几个字符串之间。

阅读(1732) | 评论(0) | 转发(0) |
0

上一篇:hdu2604 Queuing

下一篇:地道的英语

给主人留下些什么吧!~~