如何根据已排序索引的向量对 std::set 索引进行排序?

Posted

技术标签:

【中文标题】如何根据已排序索引的向量对 std::set 索引进行排序?【英文标题】:How to sort std::set of indices according to the vector of sorted indices? 【发布时间】:2020-06-15 13:45:02 【问题描述】:

我有一个类MyClass,它使用一些双精度值beta,作为类成员存储在它的成员函数g 中。它对它们进行排序并将排列存储在类成员std::vector<int> sorted_beta_ind中:

double MyClass::g() 
  // ...
  sorted_beta_ind.resize(n);
  for(unsigned int i=0; i<n; ++i) 
    sorted_beta_ind[i] = i;
  
  std::sort(sorted_beta_ind.begin(), sorted_beta_ind.end(),
            [this] (const int &a, const int &b) ++op_cmp; return beta[a] > beta[b];);
  // ...

接下来,我想在另一个成员函数f 中有几个有序的索引集,它将以与sorted_beta_ind 中相同的顺序存储索引。我正在尝试使用 std::set 对象,因此,我需要一个比较器。我想出的最佳解决方案是 lambda 函数

double MyClass::f() 
  auto ind_comp = [&order = sorted_beta_ind] (const int &a, const int &b) 
    int pos_a = ~0, pos_b = ~0;
    for(unsigned int i=0; i<order.size(); ++i) 
      if(order[i] == a) 
        pos_a = i;
      
      if(order[i] == b) 
        pos_b = i;
      
    
    return pos_a < pos_b;
  ;
  std::set<int, decltype(ind_comp)> d0, d1;
  // the rest of the function which uses std::union and std::instersection

但是在构建项目时我得到了

error: use of deleted function ‘MyClass::f()::<lambda(const int&, const int&)>& MyClass::f(int**, int)::<lambda(const int&, const int&)>::operator=(const MyClass::f()::<lambda(const int&, const int&)>&)’

这种方法行得通,还是我应该尝试完全不同的方法?

【问题讨论】:

如果您希望集合包含按与向量相同的顺序排序的索引,为什么不使用相同的比较函子呢? example 你用这组索引做什么? map&lt;index, object&gt; 不会吗? 【参考方案1】:

像您的那样捕获 lambda 表达式不是 DefaultConstructible。这正是std::set 试图做的事情,除非它接收到一个可以作为构造函数调用参数复制的比较器对象。那就是:

std::set<int, decltype(ind_comp)> d0, d1;

这里std::set 只知道比较器的类型,并将尝试使用其默认构造函数来构造一个。相反,它应该是:

std::set<int, decltype(ind_comp)> d0(ind_comp), d1(ind_comp);
//                                   ~~~~~~~^      ~~~~~~~^

【讨论】:

@Verloren 没关系,没有注意到你的 lambda 有捕获。 PiotrSkotnicki,是的,我的错。 @Verloren 这个数组再次执行两个集合的default初始化。您需要指定这两个元素,例如,using S = std::set&lt;int, decltype(ind_comp)&gt;; S d[2] S(ind_comp), S(ind_comp) ; 不是那一行 :) 但我想你很可能最终会尝试将一组复制分配给另一组,是吗? 错误消息肯定会继续说“需要来自”并给出代码中尝试复制分配 lambda 表达式的行号 @Verloren 它最终应该指向您的代码。你没有显示完整的代码,所以我不知道出了什么问题。 It compiles

以上是关于如何根据已排序索引的向量对 std::set 索引进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用二分搜索将元素插入已排序的向量中

对向量元素进行排序[关闭]

C++ 按索引对向量进行排序

对向量中具有奇数索引的数字进行排序

如何获取向量的排序索引?

R语言使用sort.list函数对向量数据进行排序(默认升序排序)返回排序后的对应索引值