您可以使用std::set_intersection 填充一个新容器,其中包含两个映射中都存在的key、value 对。 set_intersection 需要对范围进行排序(这正是您不会从 unordered_map 得到的)所以要么用 map 替换 unordered_maps 或创建临时的 maps (或临时的 @987654330 @s) 在使用 set_intersection 之前。
如果您经常需要交叉路口,我建议您将原来的 unordered_maps 替换为已订购的 maps 以提高效率:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <map>
#include <unordered_map>
#include <vector>
int main() {
std::map<int, int> mp1 {{1,0}, {2,0}, {3,0}};
std::map<int, int> mp2 {{0,0}, {2,0}, {3,0}};
// this can be unordered unless you plan to use it in an intersection later:
std::unordered_map<int, int> mp;
std::set_intersection(
mp1.begin(), mp1.end(),
mp2.begin(), mp2.end(),
std::inserter(mp, mp.begin())
);
for(auto[key, val] : mp) {
std::cout << key << ',' << val << '\n';
}
}
可能的输出:
3,0
2,0
如果您想保留unordered_maps 并且不必创建临时的sets 或maps,您可以将上面的set_intersection 替换为手动填充:
const auto& [min, max] = std::minmax(mp1, mp2,
[](auto& a, auto& b) {
return a.size() < b.size();
});
for(auto& [key, value] : min) { // iterate over the smallest map
auto fi = max.find(key); // find in the bigger map
if(fi != max.end() && fi->second == value)
mp.emplace(key, value); // add the pair if you got a hit
}
迭代最小映射的原因是将find 操作的数量保持在最低限度。考虑一个地图包含 1 个元素和其他 1000000 个元素的情况。然后,您需要 1 次查找而不是 1000000。
一个更通用的解决方案可能是用它制作一个函数模板:
template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator< std::pair<const Key, T> >
>
auto unordered_map_intersection(
const std::unordered_map<Key,T,Hash,KeyEqual,Allocator>& mp1,
const std::unordered_map<Key,T,Hash,KeyEqual,Allocator>& mp2)
{
std::unordered_map<Key,T,Hash,KeyEqual,Allocator> mp;
const auto& [min, max] = std::minmax(mp1, mp2,
[](auto& a, auto& b) {
return a.size() < b.size();
});
for(auto& [key, value] : min) { // iterate over the smallest map
auto fi = max.find(key); // find in the bigger map
if(fi != max.end() && fi->second == value)
mp.emplace(key, value); // add the pair if you got a hit
}
return mp;
}