首页 > 编程语言 > 详细

后缀数组学习笔记

时间:2019-01-31 23:27:01      阅读:227      评论:0      收藏:0      [点我收藏+]

后缀数组学习笔记

都到现在了还不会后缀数组怕不是要凉

赶快学习一发

准确地说这个东西学了很多遍?

思想我觉得我大概是懂的,就是要求一个字符串的每个后缀的排名,我们使用基数排序,每一轮得到每个位置开始长度为 \(2^{\text{轮数}}\) 的子串的排名,然后类似于一个两位数之间的基数排序,这里两位数每一位都是上一层已经计算过的一个子串的排名

具体得看代码实现,复杂度为 \(O(n\log n)\)

// 这里是定义:
// c 表示桶,每一个对应着这一个桶所对应的数的个数,前缀和即是排名
// s 是要计算 SA 的字符串

inline void get_SA() {
    rep(i, 1, n) c[x[i] = s[i]]++;
    rep(i, 2, m) c[i] += c[i - 1];
    rep(i, n, 1) sa[c[x[i]]--] = i; // 编号为 i 的物品在当前长度下排名为 c[x[i]]
    // 然后由于当前排名的物品使用了一个,所以排名上移一位(一开始的排名是最下面的排名)
    for (int k = 1; k <= n; k <<= 1) {
        int num = 0;
        rep(i, n - k + 1, n) y[++num] = i; // 这一部分没有“第二个字符”,所以在最前面
        rep(i, 1, n) if (sa[i] > k) y[++num] = sa[i] - k; // 如果一个串的结束位置在 k 之后,那么这个串一定可以作为另一个串的后一半
        rep(i, 1, m) c[i] = 0;
        rep(i, 1, n) c[x[i]]++;
        rep(i, 2, m) c[i] += c[i - 1];
        rrep(i, n, 1) sa[c[x[y[i]]]--] = y[i], y[i] = 0;
        swap(x, y);
        x[sa[1]] = 1;
        rep(i, 1, n)
            x[sa[i]] = (y[sa[i]] == y[sa[i - 1] && y[sa[i] + k] == y[sa[i - 1] + k]) ? num : ++num;
        if (num == n) break;
        m = num;
    }
}

后缀数组学习笔记

原文:https://www.cnblogs.com/wawawa8/p/10344418.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!