いくつかの標準アルゴリズムを適用することで、2つのstd::map<string, string>
すべてのキーと値(ただし一部)のペアがtrueの場合、trueを返します。
たとえば、これらの2つのマップはequalとして評価する必要があります
map<string,string> m1, m2;
m1["A"]="1";
m2["A"]="1";
m1["B"]="2";
m2["B"]="2";
m1["X"]="30";
m2["X"]="340";
m1["Y"]="53";
m2["Y"]="0";
2つのマップのサイズが同じで、キー「X」とキー「Y」によって保存されている値を除き、すべての要素をペアで比較する必要があるとします。最初の試みは、非常に非効率的な二重ネストforループです。より良い解決策を達成できると確信しています。
あなたが正確に何を探しているのかわかりませんので、最初に完全な平等を、次に重要な平等を挙げましょう。後者はすでにあなたのニーズに合っているかもしれません。
(標準の等価性はstd::map
の独自の比較演算子を使用してテストできますが、値ごとの比較のベースとして以下を使用できます。)
std::equal
とstd::operator==
sのstd::pair
を使用して、完全な同等性をテストできます。
#include <utility>
#include <algorithm>
#include <string>
#include <iostream>
#include <map>
template <typename Map>
bool map_compare (Map const &lhs, Map const &rhs) {
// No predicate needed because there is operator== for pairs already.
return lhs.size() == rhs.size()
&& std::equal(lhs.begin(), lhs.end(),
rhs.begin());
}
int main () {
using namespace std;
map<string,string> a, b;
a["Foo"] = "0";
a["Bar"] = "1";
a["Frob"] = "2";
b["Foo"] = "0";
b["Bar"] = "1";
b["Frob"] = "2";
cout << "a == b? " << map_compare (a,b) << " (should be 1)\n";
b["Foo"] = "1";
cout << "a == b? " << map_compare (a,b) << " (should be 0)\n";
map<string,string> c;
cout << "a == c? " << map_compare (a,c) << " (should be 0)\n";
}
上記のコードに基づいて、std::equal
呼び出しに述語を追加できます。
struct Pair_First_Equal {
template <typename Pair>
bool operator() (Pair const &lhs, Pair const &rhs) const {
return lhs.first == rhs.first;
}
};
template <typename Map>
bool key_compare (Map const &lhs, Map const &rhs) {
return lhs.size() == rhs.size()
&& std::equal(lhs.begin(), lhs.end(),
rhs.begin(),
Pair_First_Equal()); // predicate instance
}
int main () {
using namespace std;
map<string,string> a, b;
a["Foo"] = "0";
a["Bar"] = "1";
a["Frob"] = "2";
b["Foo"] = "0";
b["Bar"] = "1";
b["Frob"] = "2";
cout << "a == b? " << key_compare (a,b) << " (should be 1)\n";
b["Foo"] = "1";
cout << "a == b? " << key_compare (a,b) << " (should be 1)\n";
map<string,string> c;
cout << "a == c? " << key_compare (a,c) << " (should be 0)\n";
}
新しいラムダ式を使用して、これを行うことができます。
template <typename Map>
bool key_compare (Map const &lhs, Map const &rhs) {
auto pred = [] (decltype(*lhs.begin()) a, decltype(a) b)
{ return a.first == b.first; };
return lhs.size() == rhs.size()
&& std::equal(lhs.begin(), lhs.end(), rhs.begin(), pred);
}
2014-03-12を追加
新しい汎用ラムダ式を使用して、これを行うことができます。
template <typename Map>
bool key_compare (Map const &lhs, Map const &rhs) {
auto pred = [] (auto a, auto b)
{ return a.first == b.first; };
return lhs.size() == rhs.size()
&& std::equal(lhs.begin(), lhs.end(), rhs.begin(), pred);
}
スタイルマターとして、C++ 11およびC++ 14のラムダ式をパラメーターとして直接インライン化することもできます。
bool key_compare (Map const &lhs, Map const &rhs) {
return lhs.size() == rhs.size()
&& std::equal(lhs.begin(), lhs.end(), rhs.begin(),
[] (auto a, auto b) { return a.first == b.first; });
}