【问题标题】:c++ is there a built in partial_sort that returns the location of the sorted valuesc ++是否有内置的partial_sort返回排序值的位置
【发布时间】:2022-12-25 00:30:21
【问题描述】:

我有一个包含 N 个元素的列表,想找到地点最小(或最大)的 M 值。 是否有执行此操作的内置函数(沿着 std::sort 或 std::partial_sort 的行)?

【问题讨论】:

  • 如果N(非常)大,N值中的std::make_heapM个元素,其中堆中的值是值和位置对。
  • 创建索引的并行数组(即 0、1、2、...),然后(部分)对索引数组进行排序(基于索引引用的原始数组中的值)。
  • @john:在这种情况下不需要排序/部分排序。 std::nth_element 就足够了——通常是线性的而不是 O(n log n)。
  • 您将像@john 建议的那样创建并行数组,然后使用std::nth_element 找到位于m 的项目(称之为枢轴)。 nth_element 还将数组划分为不大于其左侧枢轴的元素和不小于其右侧枢轴的项。您存储在并行数组中的索引将告诉您这些元素的位置。
  • @unknown 因为只有几百个元素,所以将它们全部存储在一个容器中就可以了。另一方面,如果您收到数十万、数百万或源源不断的元素,那么维护一个 M 项堆将是一个解决方案。堆元素将由数字和找到的位置组成。

标签: c++ algorithm sorting std


【解决方案1】:

没有内置函数。但是你可以尝试这样的事情:

  • 在您的原始数组中创建一个迭代器向量。这将比 pair<index, value> 的向量占用更少的空间,并且将使您能够最快地访问原始数据。
  • 在你的向量上调用 std::nth_element()。
  • 通过调用 std::distance(或减法,对于 c++98)获取索引。

如:

template <typename Fn>
std::vector<size_t> GetMElementsPositions(const std::vector<int>& v, size_t m,
                                          Fn&& compare) {
    assert(m != 0);
    assert(m <= v.size());

    std::vector<std::vector<int>::const_iterator> w;
    w.reserve(v.size());

    for (auto i = v.begin(); i != v.end(); ++i)
        w.push_back(i);

    std::nth_element(w.begin(), w.begin() + M, w.end(), [&compare](auto& x, auto& y) { return compare(*x, *y); });

    std::vector<size_t> r;
    r.reserve(M);
    for (auto i = w.begin(); i != w.begin() + M; ++i)
        r.push_back(std::distance(v.begin(), *i));

    return r;
}

你会在这里找到一个工作原型:https://godbolt.org/z/Y54bqo9hq

【讨论】:

    猜你喜欢
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    相关资源
    最近更新 更多