如何根据对的第二个元素对向量进行排序?

如果我有一个对的向量:

std::vector<std::pair<int, int> > vec;

是否有简单的方法可以根据对的第二个元素按 越来越多顺序对列表进行排序?

我知道我可以编写一个小函数对象来完成这项工作,但是有没有一种方法可以使用 STLstd::less的现有部分来直接完成这项工作呢?

编辑: 我知道我可以编写一个单独的函数或类来传递给第三个参数进行排序。问题是我是否可以用标准的东西来构建它。我真的希望是这样的:

std::sort(vec.begin(), vec.end(), std::something_magic<int, int, std::less>());
168494 次浏览

你必须依靠非标准的 第二名

EDIT : 使用 c + + 14,由于 lambdas 现在可以拥有 auto类型的参数,因此最好的解决方案非常容易编写。这是我目前最喜欢的解决方案

std::sort(v.begin(), v.end(), [](auto &left, auto &right) {
return left.second < right.second;
});

原答案 :

只需使用一个自定义比较器(它是 std::sort的可选第三个参数)

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


std::sort(v.begin(), v.end(), sort_pred());

如果你使用的是 C + + 11编译器,你可以使用 lambdas 编写相同的代码:

std::sort(v.begin(), v.end(), [](const std::pair<int,int> &left, const std::pair<int,int> &right) {
return left.second < right.second;
});

编辑 : 为了回应你对问题的编辑,这里有一些想法..。 如果你想要有创造性并且能够重复使用这个概念,只需要做一个模板:

template <class T1, class T2, class Pred = std::less<T2> >
struct sort_pair_second {
bool operator()(const std::pair<T1,T2>&left, const std::pair<T1,T2>&right) {
Pred p;
return p(left.second, right.second);
}
};

那么你也可以这样做:

std::sort(v.begin(), v.end(), sort_pair_second<int, int>());

甚至

std::sort(v.begin(), v.end(), sort_pair_second<int, int, std::greater<int> >());

虽然说实话,这有点过头了,只需要编写3行函数就可以了:-P

你可以像这样使用助推器:

std::sort(a.begin(), a.end(),
boost::bind(&std::pair<int, int>::second, _1) <
boost::bind(&std::pair<int, int>::second, _2));

我不知道一个标准的方法来做这同样简短,但你可以抓取 boost::bind它的所有组成的标题。

对于可重复使用的东西:

template<template <typename> class P = std::less >
struct compare_pair_second {
template<class T1, class T2> bool operator()(const std::pair<T1, T2>& left, const std::pair<T1, T2>& right) {
return P<T2>()(left.second, right.second);
}
};

你可以把它当做

std::sort(foo.begin(), foo.end(), compare_pair_second<>());

或者

std::sort(foo.begin(), foo.end(), compare_pair_second<std::less>());

使用 C + + 0x,我们可以使用 lambda 函数:

using namespace std;
vector<pair<int, int>> v;
.
.
sort(v.begin(), v.end(),
[](const pair<int, int>& lhs, const pair<int, int>& rhs) {
return lhs.second < rhs.second; } );

在这个例子中,返回类型 bool是隐式推导的。

Lambda 返回类型

当一个 lambda 函数有一个语句,这是一个返回语句时,编译器可以推断出返回类型。来自 C + + 11,5.1.2/4:

...

  • 如果复合语句的形式为 { return expression ; },则返回的表达式的类型在 lvalue-to-rvalue 转换(4.1)、 array-to-point 转换(4.2)和 function-to-point 转换(4.3)之后;
  • 否则,void

要显式指定返回类型,请使用表单 []() -> Type { },如:

sort(v.begin(), v.end(),
[](const pair<int, int>& lhs, const pair<int, int>& rhs) -> bool {
if (lhs.second == 0)
return true;
return lhs.second < rhs.second; } );

很简单 您可以使用来自算法的排序函数并添加自己的比较函数

vector< pair<int,int > > v;
sort(v.begin(),v.end(),myComparison);

现在你必须根据第二个选择进行比较 所以宣布你是“我的比较”

bool myComparison(const pair<int,int> &a,const pair<int,int> &b)
{
return a.second<b.second;
}

尝试交换对的元素,这样您就可以像平常一样使用 std::sort()