如果我有一对向量:
std::vector<std::pair<int, int> > vec;
有没有简单的方法根据对的第二个元素按升序对列表进行排序?
我知道我可以编写一个小函数对象来完成这项工作,但是有没有办法使用 STL 和 std::less
的现有部分直接完成这项工作?
编辑:我知道我可以编写一个单独的函数或类来传递给第三个参数进行排序。问题是我是否可以用标准的东西来构建它。我真的会看起来像:
std::sort(vec.begin(), vec.end(), std::something_magic<int, int, std::less>());
编辑:使用 c++14,最好的解决方案非常容易编写,这要归功于现在可以具有 auto
类型参数的 lambda。 这是我目前最喜欢的解决方案
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
它全部由标题组成。
它非常简单,您可以使用算法中的排序功能并添加您自己的比较功能
vector< pair<int,int > > v;
sort(v.begin(),v.end(),myComparison);
现在您必须根据第二个选择进行比较,因此将“myComparison”声明为
bool myComparison(const pair<int,int> &a,const pair<int,int> &b)
{
return a.second<b.second;
}
使用 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 ;左值到右值转换(4.1)、数组到指针转换(4.2)和函数到指针转换(4.3)后返回表达式的类型;否则无效。
要显式指定返回类型,请使用 []() -> 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; } );
if (lhs.second == 0)
?
lhs.second < rhs.second
可能返回 true
或 false
,编译器可以清楚地推导出 bool
。只是想演示 []() -> Type { }
案例。
对于可重用的东西:
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>());
尝试交换对的元素,以便您可以正常使用 std::sort()
。
不定期副业成功案例分享
pair<T1,T2>
中的operator<
不同。默认比较器使用 both 第一个和第二个元素(如果第一个元素相等)。这里只使用了第二个。"is there and easy way to sort the list in increasing order based on the second element of the pair?"