C++ 如何在C++;仅适用于密钥的子集
我想知道是否只有通过应用一些标准算法才能编写一个比较两个C++ 如何在C++;仅适用于密钥的子集,c++,stl,comparison,maps,std,C++,Stl,Comparison,Maps,Std,我想知道是否只有通过应用一些标准算法才能编写一个比较两个std::map的短函数,如果所有键值对(但有些)都为真,则返回真 例如,应将这两个贴图计算为相等 map 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”; 假设这两个映射具有相同的大小,并且它们的所有元素必须成对比较,键“X”和键“Y”存储的值除外。第一次尝试
std::map
的短函数,如果所有键值对(但有些)都为真,则返回真
例如,应将这两个贴图计算为相等
map 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”;
假设这两个映射具有相同的大小,并且它们的所有元素必须成对比较,键“X”和键“Y”存储的值除外。第一次尝试将是一个非常低效的双嵌套for循环。
我相信可以找到更好的解决方案。我不确定您到底在寻找什么,所以让我先给出完全相等,然后给出关键相等。也许后者已经适合你的需要了 完全平等 (虽然可以使用
std::map
自己的比较运算符测试标准等效性,但以下内容可以用作基于每个值的比较的基础。)
对于std::pair
s,可以使用std::equal
和std::operator==
测试完全相等:
#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";
}
C++(C++ 11)
使用新的lambda表达式,可以执行以下操作:
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);
}
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);
}
您对两个贴图相等(不相等)的定义是不明确的。除了一些,你什么意思?至少应该有多少个?相等是指“相同数量的元素和相同的键,忽略值”?如果要检查两个映射是否完全相等,==应该足够了。对不起,我不是很清楚。假设这两个映射有N个元素,但我只想比较M
m1
和m2
中都相等欢迎使用模板化解决方案…@Als已声明使用std::equal
,其中您可以指定要检查的元素范围,这样就足够了。通过比较lhs.second==rhs.second
这是一个非常完整的答案,谢谢!One还可以使用std::equal
变量自动检查两个映射是否具有相同的长度。如果我错了,请纠正我,但这不是比较映射的有效方法。建议的比较是向量式比较。我指的是成员(对)可能按不同的顺序排列,但地图将是相等的。@luizfls:谢谢您的编辑,但在这种情况下无效,因为询问者希望自定义比较。此外,您删除的代码作为答案其余部分的基础-请在尝试编辑现有答案之前仔细阅读问题。请阅读编辑前请给出完整答案。盲目地将文本分割成碎片是不好的。std::equal
-基于此的解决方案不能用于无序容器(std::unordered\u map
,std::unordered\u set
等等)。为了更好的安全性,key\u compare
模板应包含相应的static\u assert
,以确保它只能与允许的容器一起使用。否则,很容易生成无效代码。
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);
}
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);
}
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; });
}