【问题标题】:Efficiently sort subset of the vector that defines the order有效地对定义顺序的向量子集进行排序
【发布时间】:2015-03-29 21:54:40
【问题描述】:

我有定义项目顺序的向量 (0..N-1),例如 {5, 0, 4, 3, 2, 1, 7, 6}.

我必须对该向量的子集进行排序。所以,对于{0, 1, 2, 5},我应该得到{5, 0, 2, 1}

我测试了以下解决方案:

  1. 在子集中创建一组项目,然后清除子集,遍历排序向量,仅添加集合中的项目。
  2. 通过遍历排序向量创建新的排序向量,仅添加 std::lower_bound 在子集中找到的项目。

第二种解决方案似乎要快得多,尽管它需要对子集进行排序。有没有更好的解决方案?我正在使用 C++/STL/Qt,但问题可能与语言无关。

【问题讨论】:

  • 如果您要对许多小子集进行排序,那么构建一个向量来为每个项目提供其位置是值得的:{1,5,4,3,2,0, 7,6}。然后,您可以使用在该向量中进行查找的比较函子调用 std::sort。
  • Example of Marc's suggestion。 (顺便说一句,马克;您应该考虑将其发布为一个合理的答案)。
  • 是的,这可能是存储排序向量的更好方法,因为它使代码更容易。然而,这仍然是平均 O(n long n) - 我想知道是否有办法让它更快。
  • @Michal 从依赖于 N 和 n 的复杂性转变为仅依赖于 n 的复杂性对我来说已经是一个巨大的胜利......如果这对你来说还不够,没有什么能阻止你将 std::sort 替换为基数排序或任何其他专门用于小整数的排序,重点是您可以忘记排序向量,使用查找将问题减少到常规排序,这有大量文档。
  • 我愿意接受 Marc 的回答,但他将其添加为评论。有没有办法移动它来回答?

标签: c++ algorithm sorting vector


【解决方案1】:

检查此代码:-

#include <iostream>
#include <algorithm>
#include <vector>


    struct cmp_subset
    {
        std::vector<int> vorder;

        cmp_subset(const std::vector<int>& order)
        {
            vorder.resize(order.size());
            for (int i=0; i<order.size(); ++i)
                vorder.at(order[i]) = i;
        }

        bool operator()(int lhs, int rhs) const
        {
            return vorder[lhs] < vorder[rhs];
        }
    };

    int main()
    {
        std::vector<int> order = {5, 0, 4, 3, 2, 1, 7, 6};
        std::vector<int> subset = {0, 1, 2, 5};

        for (auto x : subset)
            std::cout << x << ' ';
        std::cout << '\n';

        std::sort(subset.begin(), subset.end(), cmp_subset(order));

        for (auto x : subset)
            std::cout << x << ' ';
        std::cout << '\n';

        return 0;
    }

代码复制自here

【讨论】:

  • 这个解决方案最初是由 Marc Glisse 在 cmets 部分提出的。
猜你喜欢
  • 2011-10-03
  • 2013-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多