• 后缀数组


    #include<cstdio>
    #include<cstring>
    #include<iostream> 
    using namespace std;
    const int N=1e5+5;
    char s[N];
    int len,maxx,sa[N],rank[N],sum[N],tsa[N],trank[N],height[N];
    void Radix_sort()
    {
        maxx=256;
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=len;i++)
        {
            rank[i]=s[i];
            sum[rank[i]]++;
        }
        for(int i=2;i<=maxx;i++) sum[i]+=sum[i-1];
        for(int i=len;i;i--) sa[sum[rank[i]]--]=i;
    }
    void DA()
    {
        int p;
        Radix_sort();
        trank[sa[1]]=1,p=1;
        for(int i=2;i<=len;i++)
        {
            if(rank[sa[i]]!=rank[sa[i-1]]) p++;
            trank[sa[i]]=p;
        }
        for(int i=1;i<=len;i++) rank[i]=trank[i];
        for(int j=1;p<len;j<<=1,maxx=p)
        {
            p=0;
            for(int i=len-j+1;i<=len;i++) tsa[++p]=i;
            for(int i=1;i<=len;i++) 
             if(sa[i]>j) tsa[++p]=sa[i]-j;
            memset(sum,0,sizeof(sum));
            for(int i=1;i<=len;i++)  trank[i]=rank[tsa[i]];
            for(int i=1;i<=len;i++) sum[trank[i]]++;
            for(int i=2;i<=maxx;i++) sum[i]+=sum[i-1];
            for(int i=len;i;i--) sa[sum[trank[i]]--]=tsa[i];
            trank[sa[1]]=1,p=1;
            for(int i=2;i<=len;i++)
            {
                if((rank[sa[i]]!=rank[sa[i-1]])||(rank[sa[i]+j]!=rank[sa[i-1]+j])) p++;
                trank[sa[i]]=p;
            } 
            for(int i=1;i<=len;i++) rank[i]=trank[i];
        }
        for(int i=1,k=0;i<=len;i++)
        {
            int j=sa[rank[i]-1];
            while(s[i+k]==s[j+k]) k++;
            height[rank[i]]=k;
            if(k>0) k--;
        }
    }
    int main()
    {
        scanf("%s",s+1);
        len=strlen(s+1);
        DA();
        for(int i=1;i<=len;i++) printf("%d ",sa[i]);
        printf("
    ");
        for(int i=2;i<=len;i++) printf("%d ",height[i]);
    }
  • 相关阅读:
    实用硬件篇(一)
    iOS通讯录(纯纯的干货)
    iOS社会化分享(干货)
    静态库的打包及使用(干货)
    iOS地图集成示例:百度地图POI检索
    iOS开发之KVC全解
    网络干货
    输入一个字符串,按字典序打印出该字符串中字符的所有排列(剑指offer)
    序列化二叉树
    二叉树中和为某一值的路径
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6287815.html
Copyright © 2020-2023  润新知