【后缀数组】关于后缀数组模板的注解
2014-04-24 19:54
295 查看
#include <iostream> using namespace std; const int N = 100000; int num ; int sa , rank ,height ; int wa , wb , wv , wd ; int cmp(int *r, int a, int b, int l) { return r[a] == r[b] && r[a+1] == r[b+1]; } void da(int *r, int n, int m) { int i, j, p, *x = wa, *y = wb, *t; for(i = 0; i<m; ++i) wd[i] = 0; for(i = 0; i<n; ++i) wd[x[i] = r[i]]++; for(i = 1; i<m; ++i) wd[i] += wd[i-1]; for(i = n-1; i>=0; --i) sa[--wd[x[i]]] = i; for(j = 1, p = 1; p<n; j <<= 1, m = p) { for(p = 0, i = n-j; i<n; ++i) y[p++] = i; for(i = 0; i<n; ++i) if(sa[i] >= j) y[p++] = sa[i] - j; for(i = 0; i<n; ++i) wv[i] = x[y[i]]; for(i = 1; i<m; ++i) wd[i] = 0; for(i = 0; i<n; ++i) wd[wv[i]]++; for(i = 1; i<m; ++i) wd[i] += wd[i-1]; for(i = n-1; i>=0; --i) sa[--wd[wv[i]]] = y[i]; for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i<n; ++i) { x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p - 1 : p++; } } } /* void da(int *r, int n, int m)//x,y 其实是rank数组 { //x = wa,y = wb 都是 rank 数组的意义 //因为生成x依赖y的结果,之后y又依赖于x ,使用指针避免数组拷贝 int i, j, p, *x = wa, *y = wb, *t; //基数排序,wd可以看做是桶之类的东西 for(i = 0; i<m; ++i) wd[i] = 0; for(i = 0; i<n; ++i) wd[x[i] = r[i]]++; for(i = 1; i<m; ++i) wd[i] += wd[i-1]; for(i = n-1; i>=0; --i) sa[--wd[x[i]]] = i; for(j = 1, p = 1; p<n; j <<= 1, m = p) { //由于存在第二关键字超出字符串长度的情况 //这种情况下第二关键字被赋值为 0 //故这种值为 0 的第二关键字肯定排在 rank 的前几位 //这种情况的数量是由于倍增 j 产生的, 每次都有 j 个 //因为从 n - j 位开始就没有第二关键字了 //所以 rank 直接从这里开始赋值 //rank 的前 j 位即是这些值为 0 的后缀的下标 for(p = 0, i = n-j; i<n; ++i) y[p++] = i; //处理完第二关键字为 0 的情况 //sa[i] 意味着第 i 位是哪个后缀 //按照 sa 遍历已经保证了次序 //又因为 当前后缀下标(即sa[i]) >= j 时才存在第一关键字 //所以求 sa[i] - j 即得到了rank 的值 for(i = 0; i<n; ++i) if(sa[i] >= j) y[p++] = sa[i] - j; //优化寻址的东西, 注意wv数组在下面的位置 //当然把全部wv[i]换成x[y[i]]也可以 for(i = 0; i<n; ++i) wv[i] = x[y[i]]; //按照第二关键字进行的基数排序 for(i = 1; i<m; ++i) wd[i] = 0; for(i = 0; i<n; ++i) wd[wv[i]]++; for(i = 1; i<m; ++i) wd[i] += wd[i-1]; for(i = n-1; i>=0; --i) sa[--wd[wv[i]]] = y[i]; //交换两个 rank 数组并规整,迭代求解 for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i<n; ++i) { x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p - 1 : p++; } } } */ void getHeight(int *r, int n) { int i, j, k = 0; for(i = 1; i<= n; ++i) rank[sa[i]] = i; for(i = 0; i<n; height[rank[i++]] = k) { for(k ? k-- : 0, j = sa[rank[i-1]]; r[i+k] == r[j+k]; ++k); } }
相关文章推荐
- 【后缀数组】关于后缀数组模板的注解续
- [sa][后缀数组]关于后缀数组的若干技巧
- 后缀数组练习题bzoj 1031 后缀数组模板题目
- 【后缀数组】后缀数组模板
- POj 3581 看起来不像后缀数组的后缀数组
- UOJ #35. 后缀排序 后缀数组模板题
- 后缀数组模板
- 后缀数组模板
- [总结]后缀数组: 注释+模板
- luogu #3809 【模板】后缀排序(后缀数组)
- 后缀数组模板
- 后缀数组_DC3(模板大全)
- 刘汝佳蓝书后缀数组模板解释及补全
- 【后缀数组】洛谷P3809模板题
- 【tyvj 1860】 后缀数组模板
- [总结]后缀数组: 注释+模板
- 后缀数组 模板 (敲定)
- 后缀数组模板 SuffixArray
- cf244D. Match & Catch 字符串hash (模板)或 后缀数组。。。
- 后缀数组 模板