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

模板 后缀数组

时间:2018-09-23 22:40:09      阅读:362      评论:0      收藏:0      [点我收藏+]

标签:str   sci   temp   div   超过   scanf   一个   有一个   基数排序   

(要点写注释里了)代码:求SA

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 int has[2000000];//桶,用于基数排序,ASCII字符集0~127
 5 int sa[2000000];//后缀数组,意为排名为i的后缀起始位置 
 6 int tmr[2000000];//temp_rank为构建rank的临时数组后期需要去重
 7 int rank[2000000];//排名,与sa互为逆映射,为以i起始的后缀的排名 
 8 char str[2000000];
 9 int len,cnt;
10 bool Ssame(int a,int b,int l)//去重函数,意为判断以a,b开始长度为l的子串是否相同 
11 {
12     if(a+l>len||b+l>len)
13         return false;//若有一个末尾超过总长,一定可以判定两串不相同
14     return (rank[a]==rank[b])&&(rank[a+l]==rank[b+l]);//两串排名均相同则相同 
15 }
16 int main()
17 {
18     scanf("%s",str+1);
19     len=strlen(str+1);
20     for(int i=1;i<=len;i++)
21         has[str[i]]++;//构建桶 
22     for(int i=0;i<128;i++)
23         if(has[i])
24             tmr[i]=++cnt;//tmr在第一次构建的时候意为字符所在排名 
25     for(int i=1;i<128;i++)
26         has[i]+=has[i-1];//基数排序参数 
27     for(int i=1;i<=len;i++)
28     {
29         rank[i]=str[i]; 
30         sa[has[str[i]]--]=i;
31     }
32     /*第一次从文本串转化为rank数组,其实是无需离散化的*/
33     for(int k=1;cnt!=len;k*=2)
34     {
35         cnt=0;
36         for(int i=0;i<=len;i++)
37             has[i]=0;//清空 
38         for(int i=1;i<=len;i++)
39             has[rank[i]]++;//本质是rank的排序 
40         for(int i=1;i<=len;i++)
41             has[i]+=has[i-1];//构建桶 
42         for(int i=len;i;i--)//顺序 
43             if(sa[i]>k)
44                 tmr[sa[i]-k]=has[rank[sa[i]-k]]--;//有前半部分 
45         for(int i=1;i<=k;i++)
46             tmr[len-i+1]=has[rank[len-i+1]]--;
47         for(int i=1;i<=len;i++)
48             sa[tmr[i]]=i;
49         for(int i=1;i<=len;i++)
50             if(Ssame(sa[i],sa[i-1],k))
51                 tmr[sa[i]]=cnt;
52             else
53                 tmr[sa[i]]=++cnt;
54         for(int i=1;i<=len;i++)
55             rank[i]=tmr[i];
56     }
57     for(int i=1;i<=len;i++)
58         printf("%d ",sa[i]);
59     puts("");
60     return 0;
61 }

 

模板 后缀数组

标签:str   sci   temp   div   超过   scanf   一个   有一个   基数排序   

原文地址:https://www.cnblogs.com/blog-Dr-J/p/9693692.html

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