143

ペアのベクトルがある場合:

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

ペアの2番目の要素に基づいてリストを昇順で並べ替える簡単な方法はありますか?

作業を行う小さな関数オブジェクトを作成できることは知っていますが、STLの既存の部分を使用std::lessして、作業を直接行う方法はありますか?

編集:ソートするために3番目の引数に渡す別の関数またはクラスを作成できることを理解しています。問題は、標準的なものからそれを構築できるかどうかです。私は本当に次のようになります:

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

7 に答える 7

236

編集:c ++ 14を使用すると、タイプのパラメーターを持つことができるラムダのおかげで、最良のソリューションを非常に簡単に記述できますautoこれは私の現在のお気に入りのソリューションです

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

元の回答

カスタムコンパレータを使用するだけです(これはオプションの3番目の引数です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コンパイラを使用している場合は、ラムダを使用して同じように記述できます。

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

于 2008-11-11T02:56:21.957 に答える
71

次のようにブーストを使用できます。

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

これを同じように短く簡潔にする標準的な方法はわかりませんが、boost::bindすべてがヘッダーで構成されていることは理解できます。

于 2008-11-11T06:02:04.313 に答える
30

C++0x では、ラムダ関数を使用できます。

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は暗黙的に推測されます。

ラムダの戻り値の型

ラムダ関数に 1 つのステートメントがあり、これが return ステートメントである場合、コンパイラは戻り値の型を推測できます。C++11 から、§5.1.2/4:

...

  • 複合ステートメントが、{ return expression ; }左辺値から右辺値への変換 (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; } );
于 2011-11-03T21:42:56.200 に答える
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);
    }
};

として使用できます

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

また

std::sort(foo.begin(), foo.end(), compare_pair_second<std::less>());
于 2008-11-11T11:33:34.783 に答える
1

非標準のselect2ndに依存する必要があります

于 2008-11-11T02:48:19.943 に答える
-1

std::sort()通常どおり使用できるように、ペアの要素を交換してみてください。

于 2017-01-12T07:58:48.250 に答える