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

学习笔记:后缀数组

时间:2017-01-05 00:49:34      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:blog   class   void   核心   排序   note   第一个   pre   str   

后缀数组是指对于后缀排序后,每个后缀的位置:sa[rank]=pos:排名为rank的后缀是pos->len这个后缀

note:rank[pos]=rank:位置为pos的串排名为rank

白书上的代码简洁明了,很容易理解。

核心思想:我们对于每个位置开始的后缀,不直接计算,先计算从这个位置开始,向后1位是第几小,然后向后2位,向后4位,一直到*2>n,这时就算好了后缀数组

复杂度:O(n*log(n)^2) :倍增log(n),快排log(n)

代码:

bool cp(int x,int y)
{
    //rank(2*k)[x]和rank(2*k)[y]可以由rank(k)[x],rank(k)[x+k]和rank(k)[y],rank(k)[y+k]比较得出
    if(rank[x]!=rank[y]) return rank[x]<rank[y];
    int rx=x+k<=n?rank[x+k]:-1;//当前位置是x,向后k位超出了长度,那么很明显,rank[x+k]是不存在的,也可以看做一个空串,rank=-1
    int ry=y+k<=n?rank[y+k]:-1;
    return rx<ry;
}
void sa(string s)
{
    //******排名:第几小
    n=s.length();
    for(int i=0;i<=n;i++)
    {
        sa[i]=i; rank[i]=i<n?s[i]:-1;
    }
    for(k=1;k<=n;k*=2)
    {
        sort(sa,sa+n+1,cp);//sa排序,sa存的是每个排名的位置,也就是每个排名对应的串
        //sa[0]即为排名为0的串对应的位置
        temp[sa[0]]=0;//第一个rank为0
        for(int i=1;i<=n;i++)
        {
            temp[sa[i]]=temp[sa[i-1]]+(cp(sa[i-1],sa[i]));//计算名次,因为sa已经排好序,这里计算如果两个串相等,那么排名一样,否则排名+1
        }
        for(int i=0;i<=n;i++)
        {
            rank[i]=temp[i];//直接赋值,上面那个因为是按sa排序,所以按sa赋值
        }
    }
}

 

学习笔记:后缀数组

标签:blog   class   void   核心   排序   note   第一个   pre   str   

原文地址:http://www.cnblogs.com/19992147orz/p/6250697.html

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