【问题标题】:sort operator not working in C++排序运算符在 C++ 中不起作用
【发布时间】:2012-08-26 02:31:24
【问题描述】:

我在使用排序运算符时遇到了问题,因为我只需要对对中的第一个元素进行排序。代码很简单,但不起作用:

运算符定义在:

struct sort_pred {
    bool operator()(const CromosomaIndex &left, const CromosomaIndex &right) { 
        return left.first < right.first;
    }
};

类型是

typedef std::pair<double,int> CromosomaIndex;

我正在尝试像这样对数组进行排序:

CromosomaIndex nuevo[2];
nuevo[0].first = 0.01;
nuevo[0].second = 0;
nuevo[1].first = 0.009;
nuevo[1].second = 1;
int elements = sizeof(nuevo) / sizeof(nuevo[0]);
sort(nuevo, nuevo+ elements, sort_pred());

但问题是这是对第一个和第二个元素进行排序,我只想对第一个元素进行排序并保持第二个元素不变。 有什么想法吗?

【问题讨论】:

  • 我给了你一个解决方案,让它们保持与 second 最初出现的顺序相同。但我无法从你的问题中看出这是否是你真正想要的。您是否试图分开对并在排序后让它们以不同的方式关联?这真的很不寻常,并且表明它们可能一开始就不应该是同一个对象的成员。
  • 我只需要对一个双精度数组进行排序,然后就可以恢复它们的原始索引。我正在尝试在stackoverflow.com/questions/1577475/… 中实现,但对我不起作用...谢谢回答
  • 你的意思是它不工作?排序后,nuevo[0] 将成为 {0.009,1} 对,nuevo[1] 将成为 {0.01,0}。为什么这不是你想要的?

标签: c++ sorting std-pair


【解决方案1】:

如果您希望结果取决于原始顺序,请使用std::stable_sort

【讨论】:

    【解决方案2】:

    这种方法将配对作为一个单独的单元进行排序,这是预期要做的:分解配对中的 firstsecond 是没有意义的。如果您只想对 first 项进行排序而将 second 保留在原处,您将得到一组不同的对。

    如果要将firstsecond 分开排序,请将它们放在单独的数组中(更好的是,使用vectors)并对第一个向量进行排序。然后迭代这两个向量,并生成一组新的对。

    【讨论】:

    • 感谢您的回答,我正在尝试来自stackoverflow.com/questions/1577475/… 的代码,所以我不知道有什么不同
    • @PabloAcuña 那么你的排序是正确的(参见ideone),它应该对两个项目进行排序,只比较第一个项目——这就是链接中答案背后的全部想法。 first 告诉你你看到了什么项目,第二个告诉你项目在未排序数组中的索引是什么。
    【解决方案3】:

    我不确定您是否理解另一个问题的答案,但您确实希望根据 double 值对整对进行重新排序。原始索引(int)必须附加到原始向量中位于该位置的double,以便您可以恢复该位置。请注意,如果您仅对pair 中的double 进行排序,则int 的值将是数组中的位置...根本不需要将其作为基准进行维护。

    或者,您可以考虑类似(尽管略有不同)的解决方案。创建一个整数向量,该向量使用[0..N) 范围内的值进行初始化,其中N 是双精度向量的大小。然后使用比较器函数对索引向量进行排序,而不是查看传入的值 (int),而是检查原始 double 向量中的值:

    struct dereference_cmp {
       std::vector<double> const & d_data;
       dereference_cmp( std::vector<double> const & data ) : d_data(data) {}
       bool operator()( int lhs, int rhs ) const {
          return d_data[lhs] < d_data[rhs];
       }
    };
    std::vector<double> d = ...;
    std::vector<int> ints;
    ints.reserve( d.size() );
    for ( int i = 0; i < d.size(); ++i ) ints.push_back(i);
    std::sort( d.begin(), d.end(), dereference_cmp(d) );
    

    在这种方法中,请注意没有被重新排序的是doubles,而是索引向量。在sort 完成后,索引向量将包含double 向量中的位置,使得i &lt; j => d[ ints[i] ] &lt;= d[ ints[j] ]

    请注意,在整个过程中,您要重新排序的是索引(在原始方法中能够重建未排序的向量,在这种方法中能够以排序顺序找到值)和原始向量只是为了提供排序的标准。

    还请注意,仅对索引而不是具有值和索引的修改容器进行排序的唯一原因是,如果 移动 数据的成本很高(假设每个数据都是一个不能廉价移动的大对象,作为一个包含数据数组(而不是向量)的结构)。

    【讨论】:

      猜你喜欢
      • 2017-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-30
      • 2021-05-22
      相关资源
      最近更新 更多