用于制作一组 pair<int, int> 类型元素的运算符重载

Operator overloading for making a set of elements of type pair<int, int>

如何重载一对整数的“<”(小于)运算符以将此类型的元素插入到集合中。例如,考虑以下程序

#include <stdio.h>
#include <utility>
#include <set>
using namespace std;

bool operator<(pair<int, int> a, pair<int, int> b){
  if(a.second < b.second) return true;
  if(a.second == b.second) return a.first < b.first;
  return false;
}

int main(){
  pair<int, int> a = make_pair(1, 4);
  pair<int, int> b = make_pair(2, 3);
  set<pair<int ,int> > s;
  s.insert(b);
  s.insert(a);
  set<pair<int, int> >::iterator it = s.begin();
  for(; it!=s.end(); it++){
    printf("(%d %d)\n", it->first, it->second);
  }
  if(a < b) printf("a < b\n");
  else printf("b < a\n");
}

以上代码产生的输出是:

(1 4)
(2 3)
b < a

我希望集合中的元素按对结构的第二个元素排序。如何做到这一点?

问题是 std::set 在内部使用 std::less 进行比较,并委托给标准库提供的 std::pairoperator<。这将在 firstsecond 上按字典顺序排列你的对。

但是,您也拉入整个 namespace std 并提供您自己的 operator<。在您执行 if(a<b) 的位置,名称查找将找到您自己提供的比较并使用它。这就是为什么你得到了矛盾的结果。

您可以编写自己的函数对象 my_less 并将其传递给 std::set。我建议使用 std::forward_as_tuple,但您提供的实现也可以。

#include <stdio.h>
#include <utility>
#include <set>
#include <tuple>
using namespace std;

struct my_less 
{
    bool operator()(pair<int, int> const& a, pair<int, int> const& b) const
    {
        return std::forward_as_tuple(a.second, a.first) < std::forward_as_tuple(b.second, b.first);
    }
};

int main(){
  pair<int, int> a = make_pair(1, 4);
  pair<int, int> b = make_pair(2, 3);
  set<pair<int ,int>, my_less> s;
  s.insert(b);
  s.insert(a);
  set<pair<int, int> >::iterator it = s.begin();
  for(; it!=s.end(); it++){
    printf("(%d %d)\n", it->first, it->second);
  }
  if(my_less{}(a,b)) printf("a < b\n");
  else printf("b < a\n");
}

Live Example.

std::set 维护其元素之间的顺序(每个值也是它自己的键,因此它必须是唯一的)。

您无法对 std::set 进行排序并颠覆此排序,但您可以定义自己的排序标准

struct sortBySecond {
  bool operator()(const pair<int, int>& e1, const pair<int, int>& e2) const {
    if (e1.second < e2.second)
      return true;
    else if (e1.second == e2.second) {
      if (e1.first < e2.first)
        return true;
      else
        return false;
    }
    else
      return false;
  }
};


int main() {
  pair<int, int> a = make_pair(1, 4);
  pair<int, int> b = make_pair(2, 3);
  set<pair<int, int>, sortBySecond> s;
  s.insert(b);
  s.insert(a);
  for (auto& el : s)
    std::cout << "(" << el.first << ";" << el.second << ")" << std::endl;
  return 0;
}

Live Example