两个unordered_map的交集

时间:2014-01-21 10:16:08

标签: c++ c++11 stl unordered-map

基本上我的问题与Intersection of two STL maps相同,但有两个unordered_maps

std::unordered_map<Key, Value> A;
std::unordered_map<Key, Value> B;

我想得到交叉点,类似于

std::unordered_map<Key, std::pair<Value, Value>> C;

其中键是A和B中的值,值分别是A和B中的一对值。

实现这一目标的最快方法是什么?目前,我迭代两者中的最小值并在第二个中查询键。幸运的是,我的密钥类型通常很容易散列,但是我没有找到一种方法来获取迭代映射的密钥的哈希值,以免计算第二个哈希值(显然:我不知道如何恢复哈希而不再重新计算它,以及在哪里找到类似find的东西,其中计算哈希为参数[1])。

感谢。

[1]是的,我知道,早期优化是许多疾病的根源。然而,我想知道这是否可能,而不是解释这将如何成为一堆错误。实际上,在某些情况下,根据用户输入,密钥可能复杂且散列成本高。

2 个答案:

答案 0 :(得分:1)

我知道你不想听,但我还是会说它:你应该在实例上缓存哈希值,这样哈希就会减少到简单的成员查找。如果实例是不可变的(或者至少,进入散列函数的部分是不可变的),那么最简单的方法是在构造函数中计算散列。

答案 1 :(得分:0)

如果密钥真的哈希值很高,你可以避免其中一次散列,但代价是从头开始使用std::unordered_map<Key, std::pair<Value, Value>>类型的A和B.第二个是默认构造的值)

假设一旦计算出交叉点后你不需要原始的A和B,你可以迭代2中的最小值(假设B是最小的):

- &GT;在C中移动B

 for (auto it = C.begin(); it != C.end();it++ ) {
   auto res = A.find(it->first);
    if(res == A.end() )
        {               
            //Can't call C.erase(it) here as it would cause problem in the loop                 
            v.push_back(it); 
        }
        else
        {
            // Assign the second value of the pair to the value obtained in A.
            it->second.second = res->second.first;
        }     
  }
for( auto it : v)
  C.erase(it);

这会让你在C中填充成对,其中pair.first是B中的值,而pair.second是A中的值

如果您需要保持A和B不变,而不是在C中移动B,只需在C中复制B.