您的位置:首页 > 其它

【后缀数组】关于后缀数组模板的注解

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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: