繁体   English   中英

检查 std::map 中是否存在值的最快方法是什么?

[英]What is the fastest way to check if value is exists in std::map?

检查std::map<int, int>中是否存在值的最快方法是什么? 我应该使用unordered map吗? 在此任务中,我不能使用任何库来代替 std。

现在,如果不检查所有值,我不知道有什么方法可以做到这一点。

最快的方法就是不做。 不要在地图中寻找,在地图中寻找

如果您需要搜索,请使用其他数据结构(或单独的映射)。

在 map 中搜索的唯一方法是线性 (O(N)),但由于迭代 map 数据结构时的缓存开销,它甚至比迭代向量更慢。

您可以使用find方法查找和元素。 地图通常由红黑树实现,具有对数搜索复杂度。

如果你需要按值搜索,那么你可以创建一个反向map,一个map,它以初始map的值作为键,对应的键是值。 您可以在第二个 map 中通过键搜索值,这将产生键。 但是,重建反转 map 需要时间和存储资源,因此只有在要搜索多次时才应该这样做。

关于值, map与列表或向量并没有真正的不同。 所以穷举(线性)搜索是最快的方法。

除非你有非常大的数据集(超过 100'000 左右)访问地图的时间应该不会打扰你,因为在任何一种情况下它都会非常小,因为你已经有了int作为键。 要检查value是否存在于 map 中,您应该只使用迭代器或std::find_if 你选择什么方式并不重要,无论如何它都是线性的(O(n))。

// both examples assume you using c++ 17 standart
// simple cycle variant
bool is_value_exists(auto const &map, int val) {
  for (auto const &[key, value] : map) {
    if (value == val) return true;
  }
  return false;
}
// find if version
#include <algorithm>
bool is_value_exists2(auto const &map, int val) {
  return std::find_if(
    map.begin(), 
    map.end(),
    [val](auto const &kv) { return kv.second == val; }
  ) != map.end();
}

每当您将键值对输入std::map实例时,还要将其指针添加到std::vector<iterator_...>变量中该元素的迭代器。

myVec[value]=myMap.find(key); // at time of inserting a new key

这样,您可以将该值用作向量中的键(索引),并在与 nullptr 比较后使用该指针直接访问 map 内容。

最大的缺点是当您从 map 中删除密钥时需要额外的簿记。如果删除操作足够频繁,您也可以使用 map 代替它,因为如果预期值范围太大(就像所有 32 位),它的内存效率不高。


您还可以将映射迭代搜索用作直接映射缓存的后备存储(它对 integer 个键(此处为值)的运行速度最快)。 所有缓存命中都将以仅按位&操作为代价提供,该操作具有一些值,如 8191、4095 等 (O(1))。 所有缓存未命中仍需要对 map 个元素进行完整迭代,这很慢 (O(N))。

所以,如果缓存命中率接近100%,就可以接近O(1),否则就是O(N),很慢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM