【问题标题】:Sort a data structure and keep record of the original indices [duplicate]对数据结构进行排序并记录原始索引[重复]
【发布时间】:2015-11-06 21:20:14
【问题描述】:

假设我有如下代码,用于在另一个数据结构中对一个数据结构的元素进行排序,但记录它们的原始索引:

std::vector<int> numbers = {..};
std::vector<std::pair<int, std::vector<int>::size_type>> temp;

for (std::vector<int>::size_type i = 0; i < numbers.size(); i++)
{
    temp.push_back({ numbers[i], i });
}

std::sort(temp.begin(), temp.end(), [](const auto& x, const auto& y) { return x.first < y.first; });

到目前为止一切顺利。但我真正想要的是将数据和索引存储在不同的数据结构中:

std::vector<int> sorted;
std::vector<std::vector<int>::size_type> indices;

使得sorted[i] 处的元素在原始数据结构中位于索引indices[i]。

除了推出我自己的排序算法,或者事后拆分数据结构,使用标准库有什么简单的技巧吗?

【问题讨论】:

标签: c++


【解决方案1】:

我们的想法是将您的数据存储在一个容器中,并让其他容器带有索引(基于不同的排序标准)。

这里的想法是编写函数对象,根据排序标准和数据容器中的值比较两个索引。

下一步是将您的函数对象传递给适当的排序函数。

【讨论】:

  • 你想为你的建议增加一个清晰的层次,还是一个例子?您似乎在引用一个您忘记包含的示例。
  • 我认为这给了我需要解决它的提示。谢谢!
【解决方案2】:

澄清 Thomas Matthew 的答案...创建索引为 0 到 n-1 的向量。使用 lambda 函数根据数据向量对索引向量进行排序。示例代码,包括可选的就地重新排序功能。

void reorder(std::vector<int>& vA, std::vector<size_t> vI);

int main()
{
    std::vector <int> vdata = { 7,2,4,5,3,1,6,0 };      // original data
    std::vector <size_t> vindex = { 0,1,2,3,4,5,6,7 };  // original indices

    std::sort(vindex.begin(), vindex.end(), [&vdata](size_t i, size_t j)
        {return vdata[i] < vdata[j];});

    for (size_t i = 0; i < vdata.size(); i++)
        std::cout << "[" << vindex[i] << "]=" << vdata[vindex[i]] << " ";
    std::cout << std::endl;
    reorder(vdata, vindex);
    for (size_t i = 0; i < vdata.size(); i++)
        std::cout << "[" << i << "]=" << vdata[i] << " ";
    return 0;
}

// every move places an element in it's final location
// vI passed by value (copy)
void reorder(std::vector<int>& vA, std::vector<size_t> vI)
{
    size_t i, j, k;
    int tA;
    for (i = 0; i < vA.size(); i++) {
        if (i != vI[i]) {
            tA = vA[i];
            k = i;
            while (i != (j = vI[k])) {
                vA[k] = vA[j];
                vI[k] = k;
                k = j;
            }
            vA[k] = tA;
            vI[k] = k;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2017-07-12
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-28
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多