关于两个标准的C ++排序对

时间:2015-08-13 14:31:47

标签: c++ sorting

我有以下vector配对值:

first 3  second 2
first 1  second 2
first 1  second 1
first 2  second 2

我想对我的矢量进行排序,结果将是

==========================
first 1  second 2
first 1  second 1
first 2  second 2
first 3  second 2

这意味着:

  • 对第一个元素进行排序。
  • 在关于第二个元素的等式排序的情况下

我的代码如下:

#include <utility>      // std::pair
#include <iostream>     // std::cout
#include <vector>

typedef std::pair<double, double> my_pair;
struct sort_pred
{
      bool operator () (const my_pair& left, const my_pair& right)
            {
                  return (left.first < right.first) && (left.second > right.second);
            }
};

int main () {
      std::vector<my_pair> data;
      data.push_back(my_pair(3,2) );
      data.push_back(my_pair(1,2) );
      data.push_back(my_pair(1,1) );
      data.push_back(my_pair(2,2) );

      for(auto a: data)
            std::cout << "first "<< a.first << "  second " << a.second << std::endl;

      std::cout << "==========================\n";
      std::sort(data.begin(), data.end(), sort_pred());  
      for(auto a: data)
            std::cout << "first "<< a.first << "  second " << a.second << std::endl;

      return 0;
}

sort_pred中的条件表达了我想做的事情,但是不正确。我错了价值观。

知道如何轻松解决这个问题吗?

7 个答案:

答案 0 :(得分:6)

您的比较器不太正确,因为如果第一次检查成功或者第一次检查成功并且第二次检查成功,您希望它返回true。如果second相等,您只想查看first s。所以像这样:

struct sort_pred
{
    bool operator()(const my_pair& left, const my_pair& right) const
    {
        if (left.first != right.first) {
            return left.first < right.first;
        }
        return left.second > right.second;
    }
};

这可以通过tuple在字典上可比较的事实来简化:

struct sort_pred
{
    bool operator()(const my_pair& left, const my_pair& right) const
    {
        return std::tie(left.first, right.second) < 
               std::tie(right.first, left.second);
    }
};

答案 1 :(得分:0)

这可以通过对谓词进行一些调整来实现:

struct sort_pred
{
    bool operator () (const my_pair& lhs, const my_pair& rhs)
    {
        return lhs.first<rhs.first || 
               (!(rhs.first<lhs.first) && lhs.second>rhs.second);
    }
};

Live demo

答案 2 :(得分:0)

您使用&amp;&amp;没有意义。它继续评估第二个元素if left.first > right.first,但实际上你只希望left.first == right.first发生这种情况。

这应该有效:

  bool operator () (const my_pair& left, const my_pair& right)
        {
              if (left.first != right.first)
                  return left.first < right.first;
              else
                  return left.second > right.second;
        }

答案 3 :(得分:0)

您必须区分更多案例:

bool operator () (const my_pair& left, const my_pair& right)
{
   if (left.first < right.first)
      return true;

   if (left.first != right.first)
      return false;

    // when primary criterion is equal:
    if (left.second > right.second) 
           // you want this to sort descending, right?
      return true;

    // .... other criteria

    return false;
}

答案 4 :(得分:0)

我认为你的谓词错了?

如果我理解正确,你想要第一个元素的优先级,并且只有在第二个元素上相等的情况下?

所以可能是这样的:

NO

答案 5 :(得分:0)

如果

,你希望A在B之前
  • 第一个小于B,或
  • 如果第一个和第一个B相等而B第二个小于第二个

的代码中
(a.first < b.first) or
((a.first == b.first) and
 (b.second < a.second))

但从编程的角度来看,这不是最理想的:现在你需要额外的operator==实现。

但由于某个值只能小于,等于或大于另一个值,您可以将其重写为

(a.first < b.first) or
(not (b.first > a.first) and
 (b.second < a.second))

答案 6 :(得分:0)

你在这里

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

typedef std::pair<double, double> my_pair;

struct sort_pred
{
    bool operator ()( const my_pair &left, const my_pair &right ) const
    {
        return ( left.first < right.first ) || 
               ( !( right.first < left.first ) && ( right.second < left.second ) );
    }
};

int main()
{
    std::vector<my_pair> data;

    data.push_back( my_pair( 3, 2 ) );
    data.push_back( my_pair( 1, 2 ) );
    data.push_back( my_pair( 1, 1 ) );
    data.push_back( my_pair( 2, 2 ) );

    std::stable_sort( data.begin(), data.end(), sort_pred() );

    for ( const auto &p : data ) std::cout << p.first << ' ' << p.second << std::endl;
}   

程序输出

1 2
1 1
2 2
3 2