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

Dav*_*man 125 c++ stl stdvector

如果我有一对矢量:

std::vector<std::pair<int, int> > vec;
Run Code Online (Sandbox Code Playgroud)

是否有简单的方法根据对的第二个元素按递增顺序对列表进行排序?

我知道我可以编写一个可以完成工作的小函数对象,但是有没有办法使用STL的现有部分并std::less直接进行工作?

编辑:我明白我可以编写一个单独的函数或类来传递给第三个参数进行排序.问题是我是否可以用标准的东西来构建它.我真的看起来像:

std::sort(vec.begin(), vec.end(), std::something_magic<int, int, std::less>());
Run Code Online (Sandbox Code Playgroud)

Eva*_*ran 192

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

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

只需使用自定义比较器(它是可选的第三个参数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());
Run Code Online (Sandbox Code Playgroud)

如果您使用的是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;
});
Run Code Online (Sandbox Code Playgroud)

编辑:为了回应您对问题的编辑,这里有一些想法......如果您真的想要有创意并且能够重复使用这个概念,那么只需制作一个模板:

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);
    }
};
Run Code Online (Sandbox Code Playgroud)

那么你也可以这样做:

std::sort(v.begin(), v.end(), sort_pair_second<int, int>());
Run Code Online (Sandbox Code Playgroud)

甚至

std::sort(v.begin(), v.end(), sort_pair_second<int, int, std::greater<int> >());
Run Code Online (Sandbox Code Playgroud)

虽然说实话,这有点矫枉过正,只需编写3行功能并完成它:-P

  • +1使用标准STL而不是Boost! (68认同)

Joh*_*itb 71

你可以像这样使用boost:

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

我不知道一种标准的方法来做到这一点同样简短,但你可以抓住boost::bind它所有的标题.


And*_*ler 30

使用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; } );
Run Code Online (Sandbox Code Playgroud)

在此示例中,bool隐式推导出返回类型.

Lambda返回类型

当lambda函数有一个语句,并且这是一个return语句时,编译器可以推导出返回类型.从C++ 11开始,§5.1.2/ 4:

...

  • 如果compound-statement的形式{ return expression ; }是lvalue-to-rvalue转换(4.1),数组到指针转换(4.2)和函数到指针转换(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; } );
Run Code Online (Sandbox Code Playgroud)


小智 30

它非常简单,您可以使用算法中的sort函数并添加自己的比较函数

vector< pair<int,int > > v;
sort(v.begin(),v.end(),myComparison);
Run Code Online (Sandbox Code Playgroud)

现在你必须根据第二个选择进行比较,因此将"myComparison"声明为

bool myComparison(const pair<int,int> &a,const pair<int,int> &b)
{
       return a.second<b.second;
}
Run Code Online (Sandbox Code Playgroud)

  • 简单而"点到点".不需要boost或特定的C++版本.+1 (5认同)

Leo*_*ans 5

对于可重复使用的东西:

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);
    }
};
Run Code Online (Sandbox Code Playgroud)

你可以用它作为

std::sort(foo.begin(), foo.end(), compare_pair_second<>());
Run Code Online (Sandbox Code Playgroud)

要么

std::sort(foo.begin(), foo.end(), compare_pair_second<std::less>());
Run Code Online (Sandbox Code Playgroud)