后缀数组算法实现

时间:2018-12-11 19:15:09

标签: c++ algorithm suffix-array

我目前正在根据本文所述的算法paper来实现广义后缀数组。 但是,我目前仍停留在第二章中的排序算法的实现上。 我当前的c ++代码大致如下所示(我的字母是小写英文字母):

std::vector<std::pair<int,int>> suffix_array(const std::vector<std::string>& ss) {
    std::vector<std::vector<std::pair<int,int>>> tmp(26);

    size_t n = 0;
    for (size_t i = 0; i < ss.size(); i++) {
       if (ss[i].length() > n) {
           n = ss[i].length();
       }

       for (size_t j = 0; j < ss[i].length(); j++) {
           tmp[ss[i][j] - 'a'].push_back(std::make_pair(i,j));
       }
    }

    // initialize pos
    std::vector<std::pair<int,int>> pos;
    std::vector<bool> bh;
    for (auto &v1 : tmp) {
       bool b = true;
       for (auto &p: v1) {
           pos.push_back(p);
           bh.push_back(b);
           b = false;
       }
    }

    // initialze inv_pos
    std::map<std::pair<int,int>,int> inv_pos;
    for (size_t i = 0; i < pos.size(); i++) {
       inv_pos[pos[i]] = i;
    }

    int H = 1;

    while (H <= n) {
        std::vector<int> count(pos.size(), 0);
        std::vector<bool> b2h(bh);

        for (size_t i = 0, j = 0; i < pos.size(); i++) {
            if (bh[i]) {
                j = i;
            }
            inv_pos[pos[i]] = j;
        }

        int k = 0;
        int i = 0;

        while (i < pos.size()) {
            int j = k;
            i = j;

            do {
                auto t = std::make_pair(pos[i].first, pos[i].second - H);

                if (t.second >= 0) {
                    int q = inv_pos[t];

                    count[q] += 1;
                    inv_pos[t] += (count[q] - 1);
                    b2h[inv_pos[t]] = true;
                }

                i++;
            } while (i < pos.size() && !bh[i]);

            k = i;
            i = j;

            do {
                auto t = std::make_pair(pos[i].first, pos[i].second - H);

                if (t.second >= 0) {
                    int q = inv_pos[t];

                    if ((j <= q) && (q < k) && (j <= (q+1)) &&
                        ((q+1) < k) && b2h[q+1]) {
                        b2h[q+1] = false;
                    }
                }

                i++;
            } while (i < k);
        }

        bh = b2h;
        for (auto &x : inv_pos) {
            pos[x.second] = x.first;
        }

        H *= 2;
    }

    return pos;
}

此刻,我的实现得到了垃圾结果。而且我从论文的算法描述中还不太了解inv_pos在每个阶段之后如何正确更新... 如果有人能发现我的实现存在问题,并通过简短的解释向我指出正确的方向,我将不胜感激。

0 个答案:

没有答案