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

后缀数组模板

时间:2016-03-27 01:28:28      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:

罗穗骞论文《后缀数组--处理字符串的有力工具》中的实现修改后的版本。

void SA(char *s, int *sa, int *sa2, int *rk, int *cnt, int *hgt){
    int n=strlen(s), m=26;
    for(int i=0; i<n; i++) rk[i]=s[i]-a;

    //counting sort
    for(int i=0; i<m; i++) cnt[i]=0;
    for(int i=0; i<n; i++) cnt[rk[i]]++;
    for(int i=1; i<m; i++) cnt[i]+=cnt[i-1];
    for(int i=n-1; i>=0; i--) sa[--cnt[rk[i]]]=i;
  
    for(int len=1; len<n; len*=2){
        //stp.1 fill sa2[]
        int p=0;
        for(int i=n-len; i<n; i++) sa2[p++]=i;
        for(int i=0; i<n; i++) if(sa[i]>=len) sa2[p++]=sa[i]-len;
        //stp.2 fill sa[], countig sort
        for(int i=0; i<m; i++) cnt[i]=0;
        for(int i=0; i<n; i++) cnt[rk[i]]++;
        for(int i=1; i<m; i++) cnt[i]+=cnt[i-1];
        for(int i=n-1; i>=0; i--) 
            sa[--cnt[rk[sa2[i]]]]=sa2[i];
        //stp.1 and stp.2 together are radix sort

        //fill rk[]
        swap(rk, sa2);
        rk[sa[0]]=0;
        for(int i=1; i<n; i++)
            rk[sa[i]]=rk[sa[i-1]]+!same(sa2, sa[i-1], sa[i], len);

        m=rk[sa[n-1]]+1;
        if(m==n) break;
    }

    //CALCULATE hgt[]
    hgt[0]=0;
    for(int i=0, j, lcp=0; i<n; i++){
        if(rk[i]){
            lcp?--lcp:0;
            j=sa[rk[i]-1];
            for(; s[j+lcp]==s[i+lcp]; lcp++);
            hgt[rk[i]]=lcp;
        }
    }  
}

 

说明:

1.针对字符集是‘a‘-‘z‘的情况

2.后缀数组sa[ ]和hight数组hgt[ ]的计算合在函数SA()中

 

后缀数组模板

标签:

原文地址:http://www.cnblogs.com/Patt/p/5324592.html

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