【问题标题】:Intersection of two unordered_maps两个 unordered_map 的交集
【发布时间】:2014-01-21 10:16:07
【问题描述】:

基本上我的问题和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] 是的,我知道,早期优化是许多疾病的根源。然而,我想知道这是否可能,而不是解释这将如何成为一堆错误。实际上,在某些情况下,根据用户输入,键 可能很复杂且散列成本很高。

【问题讨论】:

  • 如果您订购了maps,它会更简单,可能更快。
  • 你能在你的类中缓存散列值吗?然后,在您的哈希函数中,您可以检查哈希是否已被计算并返回。如果任何键发生变化,请记住重新计算存储的哈希值。
  • @Alan:是的,我想过,但我想避免这种情况。
  • 我建议您将示例输入和输出进行澄清,如果在 A 中找到某个键​​但在 B 中没有找到该算法应该怎么办?
  • 任何交叉路口都会这样做:忽略。

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


【解决方案1】:

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

【讨论】:

  • 你说得对,这不是我要找的 :) 不过还是谢谢。
【解决方案2】:

如果密钥真的散列成本很高,则可以避免其中一个散列,但代价是从一开始就具有 std::unordered_map&lt;Key, std::pair&lt;Value, Value&gt;&gt; 类型的 A 和 B。(使用 pair.second 到默认构造值)

假设在计算交集后您不需要原始 A 和 B,您可以只遍历 2 中的最小值(假设 B 是最小的):

--> 在 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 不变,而不是将 B 移动到 C 中,只需将 B 复制到 C 中即可。

【讨论】:

  • 谢谢,但这真的不是问题,我的地图是分开的,不能从一开始就这样压缩。
猜你喜欢
  • 1970-01-01
  • 2016-01-20
  • 2011-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-30
  • 1970-01-01
相关资源
最近更新 更多