あなたが説明したコードを実際に書いた場合、それはあなたが望むことを正確に行います:
比較.cpp:
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
using namespace std;
typedef pair<vector<int>, string> Country;
int main(int, char*[]) {
vector<Country> v;
while (cin.good()) {
string name;
int g, s, b;
cin >> name >> g >> s >> b;
vector<int> c;
c.push_back(g);
c.push_back(s);
c.push_back(b);
v.push_back(make_pair(c, name));
}
sort(v.begin(), v.end());
for (vector<Country>::const_iterator it = v.begin(); it != v.end(); ++it) {
cout << it->second << " " << it->first[0]
<< " " << it->first[1] << " " << it->first[2] << "\n";
}
return 0;
}
比較:
US 3 2 1
CA 4 1 3
DE 1 3 5
FR 1 3 5
BE 1 3 5
RU 3 1 2
今これを行います:
$ clang++ -o compare compare.cpp
$ ./compare < compare.in
BE 1 3 5
DE 1 3 5
FR 1 3 5
RU 3 1 2
US 3 2 1
CA 4 1 3
最初に金メダル (最初に BE/DE/FR、次に RU/US、次に CA)、次が銀 (RU、次に US)、次が銅 (ただし、これは私の入力では思いつきませんでした) で並べ替えられている (昇順) ことに注意してください。 )、次に名前 (BE、次に DE、次に FR)。まさにあなたが求めたもの。
(まあ、実際にはアルファベット順を要求しましたが、これは g、s、および b の数字順を実行します。これはおそらくあなたが望むものです (つまり、たとえば、2 つの金メダルは 11 より多い)。そうでない場合は、比較する前に、int を文字列化する独自の比較ファンクターを作成する必要があります。)
では、なぜこれが機能するのでしょうか。の定義を見るstd::pair
と、辞書順で比較されます。つまり、lhs.first
vs.を比較し、 s が等しい場合にのみvs.rhs.first
に進みます。また、 の定義を見ると、辞書式の順序でも比較されます。つまり、 vs. を比較し、s が等しい場合にのみvs.に移動します。以下同様です。そして、それはまさにあなたがここで求めている比較順序です.lhs.second
rhs.second
first
std::vector
lhs[0]
rhs[0]
lhs[1]
rhs[1]
[0]
あなたのコメントから、国名ではなく、数値の通常の並べ替え順序を逆にしたいようです。そのためには、独自のコンパレーターを定義する必要があります。ただし、問題は、pair と vector が希望どおりに並べ替えられないことではなく、int が希望どおりに並べ替えられないことに注意してください。
これは、理解できれば非常に些細なことなので、ただ答えを出すのではなく、順を追って説明します。
まず、デフォルトの並べ替えが (実際には、文字通りではなく) 実行されることは次のとおりです。
struct CountryComparator {
bool operator()(const Country& lhs, const Country& rhs) const {
if (!(lhs.first == rhs.first))
return (lhs.first < rhs.first);
return (lhs.second < rhs.second);
}
};
==
(私はandのみを使用するつもりはないことに注意して<
ください。int を比較しているだけなので、これはあなたの場合は問題ではありませんが、STL は、すべてのアルゴリズムが唯一のクラスでも機能するはずであるという考えに基づいて設計されています。これら 2 つの演算子をサポートしており、これは良い習慣です。)
ベクトル比較を展開するとかなり冗長になるので、気にしないでください。ベクトルの一部のメンバーの並べ替え順序を実際に逆にしたい場合は、これを行う必要がありますが、ベクトル全体の並べ替え順序を逆にしようとしています。これは、並べ替えを逆にすることと同じです。ベクトル自体の順序。したがって、これを定義するだけです:
struct CountryComparator {
bool operator()(const Country& lhs, const Country& rhs) const {
if (!(lhs.first == rhs.first))
return (rhs.first < lhs.first);
return (lhs.second < rhs.second);
}
};
次に、ソート行を次のように変更します。
sort(v.begin(), v.end(), CountryComparator());
それでは試してみましょう:
$ ./compare < compare.in
CA 4 1 3
US 3 2 1
RU 3 1 2
BE 1 3 5
DE 1 3 5
FR 1 3 5
4 つのゴールドを持つ CA は、他の誰よりも進んでいます。次に、US と RU がそれぞれ 3 つの金を持ち、銀の順に並べ替えられます。2 銀メダルの US が 1 位です。次に、BE、DE、FR、それぞれ 1 ゴールド、同じ数のシルバーと同じ数のブロンズをアルファベット順に並べ替えます。