基数排序
基数排序这个东西是后缀数组要用到的,是字符串排序非常好的算法
思想是用桶,从最长的串最后的内一位往前走(注意是从后往前走,因为前面的优先级是最大的),枚举每一个串(如果这个串在这一位没有东西,这一位就是char(0),可以在输入前初始化),把当前串装进当前位上的字符对应的桶中(装id即可)(装的时候用队列,或者别的什么高级的搞法,我只会用队列装一。一)
然后按照ASCII编码递增的方式从桶中把串拿出来,还是用队列的形式搞一个rank数组
枚举串的时候是根据rank枚举的(如果1-n枚举就没啥意义了,这个比较好想),往桶里装串的时候装的也是i对应的rank
用图描述过程大概是酱紫
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 int n; char a[110000][10]; 8 int tong[210][110000]; 9 int rank[110000]; 10 int max_len=0; 11 int main(){//freopen("ddd.in","r",stdin); 12 cin>>n; 13 for(int i=1;i<=n;i++){ scanf("%s",&a[i]); int _l=strlen(a[i]); max_len=max(max_len,_l);} 14 for(int i=1;i<=n;i++) rank[i]=i; 15 for(int t=max_len-1;t>=0;t--){ 16 for(int i=0;i<=200;i++) 17 tong[i][0]=0; 18 for(int i=1;i<=n;i++) 19 tong[a[rank[i]][t]][++tong[a[rank[i]][t]][0]]=rank[i]; 20 int _top=0; 21 for(int i=0;i<=200;i++) 22 for(int j=1;j<=tong[i][0];j++) 23 rank[++_top]=tong[i][j]; 24 } 25 for(int i=1;i<=n;i++) 26 printf("%d ",rank[i]); 27 putchar('\n'); 28 return 0; 29 }