*后缀数组

来源:互联网 发布:仰斜式挡土墙计算软件 编辑:程序博客网 时间:2024/05/18 02:12
今天是2017/5/31,DCDCBigBig的第十六篇博文

后缀数组(SA+Rank+Height)

#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;int rank[10001],sa[10001],height[10001],buc[10001],x[10001],y[10001],n,len;char st[10001]; bool cmp(int *s,int n,int m,int x){    return s[n]==s[m]&&s[n+x]==s[m+x];}void initsa(int n,int m){    memset(buc,0,sizeof(buc));    for(int i=0;i<n;i++)buc[x[i]=st[i]]++;    for(int i=1;i<m;i++)buc[i]+=buc[i-1];    for(int i=len-1;i>=0;i--)sa[--buc[x[i]]]=i;    for(int j=1,p=1;p<n;j*=2,m=p){        p=0;        for(int i=n-j;i<n;i++)y[p++]=i;        for(int i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;        memset(buc,0,sizeof(buc));        for(int i=0;i<n;i++)buc[x[y[i]]]++;        for(int i=1;i<m;i++)buc[i]+=buc[i-1];        for(int i=n-1;i>=0;i--)sa[--buc[x[y[i]]]]=y[i];        swap(x,y);        int i;        for(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++;        }    }}void initra(){    for(int i=0;i<len;i++)rank[sa[i]]=i;}void initheight(){    int j,k=0;    for(int i=0;i<len;i++){        if(k)k--;        j=sa[rank[i]-1];        while(st[i+k]==st[j+k])k++;        height[rank[i]]=k;    }}int main(){    scanf("%s",st);    len=(int)strlen(st);    initsa(len,128);    initra();    initheight();    for(int i=0;i<len;i++){        printf("%d",rank[i]);    }    printf("\n");    for(int i=0;i<len;i++){        printf("%d",sa[i]);    }    printf("\n");    for(int i=0;i<len;i++){        printf("%d",height[i]);    }    return 0;}

原创粉丝点击