ペアの2番目の要素に基づいてペアのベクトルをソートするにはどうすればよいですか?
質問
ペアのベクトルがある場合:
std::vector<std::pair<int, int> > vec;
ペアの2番目の要素に基づいてリストを昇順で並べ替える簡単な方法はありますか?
作業を行う小さな関数オブジェクトを作成できることはわかっていますが、 STL および std :: less
の既存の部分を使用して、直接作業しますか?
EDIT:別の関数またはクラスを記述して、3番目の引数に渡してソートできることを理解しています。問題は、標準のものから構築できるかどうかです。私は本当に次のようになります:
std::sort(vec.begin(), vec.end(), std::something_magic<int, int, std::less>());
解決
編集:c ++ 14を使用すると、最適なソリューションは、 auto
型のパラメーターを持つことができるラムダのおかげで非常に簡単に記述できます。 これは私の現在のお気に入りのソリューションです
std::sort(v.begin(), v.end(), [](auto &left, auto &right) {
return left.second < right.second;
});
カスタムコンパレータを使用するだけです( std :: sort
のオプションの3番目の引数です)
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
他のヒント
次のようにブーストを使用できます:
std::sort(a.begin(), a.end(),
boost::bind(&std::pair<int, int>::second, _1) <
boost::bind(&std::pair<int, int>::second, _2));
これを同様に短く簡潔に行う標準的な方法はわかりませんが、 boost :: bind
はすべてヘッダーで構成されています。
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
が暗黙的に推測されます。
ラムダリターンタイプ
ラムダ関数に単一のステートメントがあり、これがreturnステートメントである場合、コンパイラは戻り値の型を推測できます。 C ++ 11から&#167; 5.1.2 / 4:
...
- compound-statementの形式が
{return expression; }
左辺値から右辺値への変換(4.1)、配列からポインターへの変換(4.2)、および関数からポインターへの変換(4.3)後に返される式のタイプ;- それ以外の場合、
void
。
戻り値の型を明示的に指定するには、 []()-&gt;の形式を使用します次のように、{}
と入力します。
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; } );
非常に簡単です アルゴリズムのソート関数を使用し、独自の比較関数を追加します
vector< pair<int,int > > v;
sort(v.begin(),v.end(),myComparison);
2番目の選択に基づいて比較を行う必要があります 宣言してください&quot; myComparison&quot; as
bool myComparison(const pair<int,int> &a,const pair<int,int> &b)
{
return a.second<b.second;
}
再利用可能なもの:
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>());
非標準の select2nd に依存する必要がありますp>
ペアの要素を交換して、通常どおり std :: sort()
を使用できるようにします。