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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/279854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:18:00  来源:igfitidea点击:

How do I sort a vector of pairs based on the second element of the pair?

c++stlstdvector

提问by David Norman

If I have a vector of pairs:

如果我有一个成对的向量:

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

Is there and easy way to sort the list in increasing order based on the second element of the pair?

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

I know I can write a little function object that will do the work, but is there a way to use existing parts of the STLand std::lessto do the work directly?

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

EDIT: I understand that I can write a separate function or class to pass to the third argument to sort. The question is whether or not I can build it out of standard stuff. I'd really something that looks like:

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

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

回答by Evan Teran

EDIT: using c++14, the best solution is very easy to write thanks to lambdas that can now have parameters of type auto. This is my current favorite solution

编辑:使用 c++14,最好的解决方案很容易编写,这要归功于现在可以具有类型参数的 lambda auto这是我目前最喜欢的解决方案

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


Just use a custom comparator (it's an optional 3rd argument to std::sort)

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

If you're using a C++11 compiler, you can write the same using lambdas:

如果您使用的是 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;
});

EDIT: in response to your edits to your question, here's some thoughts ... if you reallywanna be creative and be able to reuse this concept a lot, just make a template:

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

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);
    }
};

then you can do this too:

那么你也可以这样做:

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

or even

甚至

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

Though to be honest, this is all a bit overkill, just write the 3 line function and be done with it :-P

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

回答by Johannes Schaub - litb

You can use boost like this:

您可以像这样使用提升:

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

I don't know a standard way to do this equally short and concise, but you can grab boost::bindit's all consisting of headers.

我不知道一个标准的方法来做到这一点同样简短,但你可以抓住boost::bind它全部由标题组成。

回答by Ezio

Its pretty simple you use the sort function from algorithm and add your own compare function

使用算法中的排序函数并添加自己的比较函数非常简单

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

Now you have to make the comparison based on the second selection so declare you "myComparison" as

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

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

回答by Andreas Spindler

With C++0x we can use lambda functions:

在 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; } );

In this example the return type boolis implicitly deduced.

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

Lambda return types

Lambda 返回类型

When a lambda-function has a single statement, and this is a return-statement, the compiler can deduce the return type. From C++11, §5.1.2/4:

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

...

  • If the compound-statement is of the form { return expression ; }the type of the returned expression after lvalue-to-rvalue conversion (4.1), array-to-pointer conversion (4.2), and function-to-pointer conversion (4.3);
  • otherwise, void.

...

  • 如果复合语句是{ return expression ; }左值到右值转换 (4.1)、数组到指针转换 (4.2) 和函数到指针转换 (4.3) 后返回表达式的类型的形式;
  • 否则,void

To explicitly specify the return type use the form []() -> Type { }, like in:

要明确指定返回类型,请使用 form []() -> 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; } );

回答by Leon Timmermans

For something reusable:

对于可重复使用的东西:

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);
    }
};

You can use it as

您可以将其用作

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

or

或者

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

回答by Greg Rogers

You'd have to rely on a non standard select2nd

你必须依赖一个非标准的select2nd

回答by hadizadeh.ali

Try swapping the elements of the pairs so you can use std::sort()as normal.

尝试交换对的元素,以便您可以std::sort()正常使用。