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

发布于 2024-07-08 20:57:05 字数 442 浏览 6 评论 0原文

如果我有一个对向量:

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

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

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

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

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

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 STL and std::less to do the work directly?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

扮仙女 2024-07-15 20:57:05

编辑:使用 c++14,最好的解决方案非常容易编写,这要归功于 lambda 表达式现在可以具有 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 编译器,您可以使用 lambda 编写相同的内容:

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

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

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

ORIGINAL ANSWER:

Just use a custom comparator (it's an optional 3rd argument to 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:

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 really wanna 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

|煩躁 2024-07-15 20:57:05

你可以像这样使用 boost:

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

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

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::bind it's all consisting of headers.

清晨说晚安 2024-07-15 20:57:05

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

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

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

bool myComparison(const pair<int,int> &a,const pair<int,int> &b)
{
       return a.second<b.second;
}
幻梦 2024-07-15 20:57:05

在 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 函数只有一条语句且这是一个 return 语句时,编译器可以推断出返回类型。 来自 C++11,第 5.1.2/4 节:

...

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

要显式指定返回类型,请使用 []() -> 形式 输入 { },例如:

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

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

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 bool is implicitly deduced.

Lambda return types

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:

...

  • 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.

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

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; } );
我一直都在从未离去 2024-07-15 20:57:05

对于可重复使用的东西:

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

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>());
方觉久 2024-07-15 20:57:05

您必须依赖非标准 select2nd

You'd have to rely on a non standard select2nd

夕色琉璃 2024-07-15 20:57:05

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文