如何仅针对键的子集有效地比较 C++ 中的两个字符串映射
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8473009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to efficiently compare two maps of strings in C++ only for a subset of the keys
提问by linello
I'm wondering if only by applying some standard algorithms is possible to write a short function which compare two std::map<string, string>
and returns true if all the key-value (but some) pairs are true.
我想知道是否仅通过应用一些标准算法就可以编写一个短函数,该函数比较两个std::map<string, string>
并在所有键值对(但有些)都为真时返回真。
For example, these two maps should be evaluated as 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";
Suppose that the two maps have same size and all their elements must be pairwise compared except the value stored by the key "X" and key "Y". A first attempt would be a very inefficient double nested for loop. I'm sure a better solution can be achieved.
假设这两个映射具有相同的大小,并且除了键“X”和键“Y”存储的值之外,它们的所有元素都必须成对比较。第一次尝试将是一个非常低效的双嵌套 for 循环。我相信可以实现更好的解决方案。
回答by Sebastian Mach
I am not sure what exactly you are looking for, so let me first give complete equality and then key equality. Maybe the latter fits your needs already.
我不确定你到底在寻找什么,所以让我先给出完全平等,然后是关键平等。也许后者已经符合您的需求。
Complete Equality
完全平等
(While standard equivalence can be tested using std::map
's own comparison operators, the following can be used as a base for a comparison on a per-value basis.)
(虽然可以使用std::map
自己的比较运算符测试标准等价性,但以下内容可用作基于每个值进行比较的基础。)
Complete equality can be tested using std::equal
and std::operator==
for std::pair
s:
可以使用std::equal
和std::operator==
for来测试完全相等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";
}
Key Equality
关键平等
C++2003
C++2003
Based on the above code, we can add a predicate to the std::equal
call:
基于上面的代码,我们可以在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";
}
C++ (C++11)
C++ (C++11)
Using the new lambda expressions, you can do this:
使用新的 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);
}
C++ (C++14)
C++ (C++14)
added 2014-03-12
添加 2014-03-12
Using the new generic lambda expressions, you can do this:
使用新的通用 lambda 表达式,您可以执行以下操作:
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);
}
As a style-matter, you can also inline the lambda expressions in C++11 and C++14 directly as a parameter:
作为样式问题,您还可以直接将 C++11 和 C++14 中的 lambda 表达式作为参数内联:
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; });
}