码迷,mamicode.com
首页 > 编程语言 > 详细

后缀数组

时间:2018-02-03 23:17:01      阅读:323      评论:0      收藏:0      [点我收藏+]

标签:pre   pos   --   can   问题   main   string   blog   自己   

后缀数组

今天被老师 强行
灌输后缀数组
然后就看了下
在代码中写的注释是我对sa的一点理解
有问题欢迎指出 3Q

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::swap;
const int maxn=2000010;

char c[maxn];
int s[maxn],sa[maxn];//后缀排名的位置
int rank[maxn];//后缀排名
int height[maxn];//常规操作
int saf[maxn];//用saf[]作为第2关键字后缀的第一关键字
int cs[maxn];//基数排序中的排名计数器
int n,m;
void rsort() {//第二关键字基数排序
    for(int i=0;i<=m;++i)cs[i]=0;
    for(int i=1;i<=n;++i)cs[rank[saf[i]]]++;
    for(int i=1;i<=m;++i)cs[i]+=cs[i-1];
    for(int i=n;i>=1;--i)sa[cs[rank[saf[i]]]--]=saf[i];//利用第二关键字排名更新sa
}
int cmp(int *f,int x,int y,int w) {
    return f[x]==f[y]&&f[x+w]==f[y+w];//cmp 
}
void get_sa() {
    for(int i=1;i<=n;++i)rank[i]=s[i],saf[i]=i;//此时saf[i]指向自己作为第一关键字的后缀
    m=127;rsort();
    for(int p=1,w=1,i;p<n;w<<=1,m=p) {//w为倍增长度,<选取第几位作为第二关键字>
        for(i=n-w+1,p=0;i<=n;++i)saf[++p]=i;
        for(i=1;i<=n;++i)if(sa[i]>w)saf[++p]=sa[i]-w;//利用上次的sa[]值更新下一次的saf[]
        rsort();swap(rank,saf);rank[sa[1]]=p=1;//p用来记录已经不需要再比较'第三关键字的'的后缀//当p=n是说明排序完成
        for(i=2;i<=n;++i)rank[sa[i]]=cmp(saf,sa[i],sa[i-1],w)?p:++p;//比较第一关键词与自己排名相临的,若第二关键字相同则需继续比较
    }
    //int j,k=0;
    //for(int i=1;i<=n;height[rank[i++]]=k)
      //  for(k=k?k-1:k,j=sa[rank[i]-1];s[i+k]==s[j+k];++k);
}

int main() {
    scanf("%s",c+1);
    n=strlen(c+1);
    for(int i=1;i<=n;++i)s[i]=c[i];
    s[0]=s[n+1]=-1;
    get_sa();
    for(int i=1;i<=n;++i) {
        printf("%d ",sa[i]);
    }
    return 0;
}

后缀数组

标签:pre   pos   --   can   问题   main   string   blog   自己   

原文地址:https://www.cnblogs.com/sssy/p/8410902.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!