算法模板——后缀数组
来源:互联网 发布:淘宝客佣金比例怎么算 编辑:程序博客网 时间:2024/06/17 05:28
后缀数组是什么?可以吃吗?
不可以吃,它是给一个字符串的所有后缀进行排序的算法。
如:一个字符串aabaaaab,它的后缀排好序后起始位置分别是:4 5 6 1 7 2 8 3
显然如果暴力去排序时间复杂度为我才不会告诉你其实是我不会DC3算法呢)。
接下来定义如下几个数组:
引用大佬图解:
倍增法的主要内容?
每次对长度为
再次引用大佬图解:
这张图是什么意思呢?
就是:x和y分别作为第一关键字和第二关键字,进行排序,以这一次排序的结果作为下一次排序的参考。
怎么排序?
需要排序的范围不超过
时间复杂度?
代码
温馨提示:复制到记事本上并将tab键调成8格效果更佳
#include <cstdio>#include <cstring>const int maxn=100000;char s[(maxn<<1)+10];int sa[(maxn<<1)+10],rank[(maxn<<1)+10],tmp[(maxn<<1)+10];int sum[(maxn<<1)+10],a[(maxn<<1)+10],n;inline int swap(int *&x,int *&y)//指针swap{ int *t=x; x=y; y=t; return 0;}inline int suffix_sort(){ int *x=rank,*y=tmp,m=26; //先排序 for(register int i=1; i<=n; ++i) { x[i]=a[i]; y[i]=i; ++sum[x[i]]; } for(register int i=1; i<=m; ++i) { sum[i]+=sum[i-1]; } for(register int i=n; i; --i) { sa[sum[x[i]]]=i; --sum[x[i]]; } int len=1,p=1; while(p<n) { m=p; p=0; //每次循环设一下初值,然后排序 for(register int i=n-len+1; i<=n; ++i) { ++p; y[p]=i; } for(register int i=1; i<=n; ++i) { if(sa[i]-len>0) { ++p; y[p]=sa[i]-len; } } //前面是按第二关键字排序,接下来按第一关键字排序 for(register int i=0; i<=m; ++i) { sum[i]=0; } for(register int i=1; i<=n; ++i) { ++sum[x[y[i]]]; } for(register int i=1; i<=m; ++i) { sum[i]+=sum[i-1]; } for(register int i=n; i; --i) { sa[sum[x[y[i]]]]=y[i]; --sum[x[y[i]]]; } swap(x,y); //现在y数组已经没有用了 p=1; x[sa[1]]=1; //下一个步骤是去重 for(register int i=2; i<=n; ++i) { if(!((y[sa[i-1]]==y[sa[i]])&&(y[sa[i-1]+len]==y[sa[i]+len]))) { ++p; } x[sa[i]]=p; } len<<=1; } //如果所有的都已经排好序,那么就没有必要排下去了,退出 p=0; //在上面计算的步骤中x数组记录的值可能不是真正的rank数组,需要重新计算 for(register int i=1; i<=n; ++i) { ++p; rank[sa[i]]=p; } return 0;}int main(){ scanf("%s",s+1); n=strlen(s+1); for(register int i=1; i<=n; ++i) { a[i]=s[i]-'a'+1; } suffix_sort(); for(register int i=1; i<=n; ++i) { printf("%d\n",sa[i]); } return 0;}
阅读全文
0 0
- 算法模板——后缀数组
- 后缀数组 倍增算法模板
- 后缀数组倍增算法模板详解
- 【后缀数组】后缀数组模板
- 后缀数组——倍增算法
- ACM常用模板——数据结构——后缀数组
- 后缀数组(模板)——来自MovingforACM
- 后缀数组入门——初步理解及模板
- SA(后缀数组)——倍增法模板
- 后缀数组【模板】
- 【后缀数组模板】
- 后缀数组模板
- 后缀数组模板
- 【模板】后缀数组
- 后缀数组模板
- 后缀数组模板
- 后缀数组模板
- 【省选】【后缀数组】模板
- VirtualBox虚拟机配置CentOS7网络图文详解教程(转)
- Logback、Log4J及slf4J日志框架分析对比及在Spring Boot中的使用
- 如何使用JDK中的keytool工具获取keysotre签名里面的信息
- 关于Struts2+spring中使用百度UEditor编辑器显示未找到上传数据的解决方法
- Qt生成文件依赖打包
- 算法模板——后缀数组
- js组件-bootstrap table 客户端分页与搜索总结
- 获取免费的代理ip
- iOS
- Android使用Thread的interrupt与sleep,重启或暂停线程任务
- IE8兼容canvas和一些CSS3属性
- python根据函数进行列表排序
- MySQL数据库学习07-查询数据:聚合函数
- 我们物联网专业的嵌入式实习-day04(开发智能家居系统-结构体、文件IO与进程)