后缀数组代码理解加注释
来源:互联网 发布:商品条码数据库下载 编辑:程序博客网 时间:2024/04/26 15:56
一段三四十行的代码却看了一个下午,仿佛又回到了刚学C语言的时候,终于看懂了,写下注释,晚上写题。
后缀数组是用来在线处理模式串匹配问题的算法,比如有一个文本串aabaaaab,我们求出一个sa数组,sa[i] = x表示第该文本串中第i小的后缀串的头字母是x,sa[0] = 3(aaaab),sa[1] = 4(aaab),sa[2] = 5(aab),sa[7]=2(baaaab),暴力处理后缀排序的复杂度为n*logn*logn(快排*比较),有一种更优的做法,被成为倍增法,复杂度n*logn
倍增法代码:很有点抽象难懂T_T
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 1000;const int maxasc = 128; //ascII码[0,127]char s[maxn];int sa[maxn],t1[maxn],t2[maxn],c[maxn],n;void debug(){ for(int i=0; i<n; i++) printf("%d ",sa[i]); printf("\n");}void build_sa(int m){ int *x = t1,*y = t2; //第一遍实际就是对s数组稳定排序,使用的是基数排序 for(int i=0; i<m; i++) c[i] = 0; for(int i=0; i<n; i++) c[x[i] = s[i]]++; for(int i=1; i<m; i++) c[i] += c[i-1]; for(int i=n-1; i>=0; i--) sa[--c[x[i]]] = i; for(int k=1; k<=n; k = k<<1) //每次扩展两倍 { int p = 0; //利用sa数组直接排序第二关键字 //实际是认为没有第二关键字,即不存在后k个字符的串的第二关键字最小,y[i] = x 表示第二关键字第i小的串的首字母是i for(int i=n-k; i<n; i++) y[p++] = i; //实际是认为没有第二关键字,即不存在后k个字符的串的第二关键字最小 //如果sa[i]小于k,第一关键字不够k个字符 for(int i=0; i<n; i++) if(sa[i] >= k) y[p++] = sa[i]-k; //基数排序第一关键字 //已经知道第二关键字的大小顺序了,扔到桶(c数组)里来一趟基数排序 for(int i=0; i<m; i++) c[i] = 0; for(int i=0; i<n; i++) c[x[y[i]]]++; for(int i=0; i<m; i++) c[i] += c[i-1]; for(int i=n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i]; //根据sa和y数组计算x数组 //x数组实际是用来确定首字母为第i号字符,连续k个字母的串的相对大小的,所以最开始x[i]=s[i] swap(x,y); p = 1; x[sa[0]] = 0; //从最小的串开始,赋予串一个整数值代表大小,aa = aa = 1,ab = 2,ba = 3等等 for(int i=1; i<n; i++) x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k] ? p-1 : p++; //每个串都彼此大小不同了,事实上后缀就是应该所有都不相等的,相对大小已确定,退出循环 if(p >= n) break; m = p; //关键字的取值范围发生了变化,现在只有p个不同的值 } debug();}int main(){ scanf("%s",s); n = strlen(s); build_sa(maxasc); return 0;}
0 0
- 后缀数组代码理解加注释
- 【数据结构】后缀数组模板+代码理解
- 后缀数组模版+注释
- [总结]后缀数组: 注释+模板
- 后缀数组模板代码
- 后缀数组代码详解
- 计算器代码加注释版
- 后缀数组模板(理解)
- 自动加注释(理解错误了)
- 冒泡排序加个人理解注释
- android 代码 给加一下注释
- python 3.3 代码中加中文注释
- Eclipse改代码快速加注释
- iOS图片上传代码加注释
- achartengine表格折线图代码加注释
- 关于代码注释的理解
- iOS 注释方法大全 代码块加快捷键自定义注释
- iOS 注释方法大全 代码块加快捷键自定义注释
- HTTP3xx重定向
- python caffe training solve.py
- C语言 打印菱形(可变行数)
- MySQL中函数CONCAT及GROUP_CONCAT
- poj 2230 Watchcow(欧拉回路)
- 后缀数组代码理解加注释
- 算法分析与设计-动态规划0
- C++利用socket的客户端和服务器之间传输文件
- Spring Data JPA使用JpaRepository自动装配报No qualifying bean of type错误
- 51nod 1065 最小正子段和(前缀和)
- C++ hdu 2026 首字母大写
- 判断一棵二叉树是否是另一棵二叉树的子树
- 【NOIP 模拟题】[T1]return(模拟)
- 19、Jquery入门