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

zynd9foi  于 2023-01-15  发布在  其他
关注(0)|答案(5)|浏览(519)

检查std::map<int, int>中是否存在value的最快方法是什么?我应该使用unordered map吗?在这个任务中,我不能使用任何库来代替std。
现在,我不知道有什么方法可以做到这一点,而不检查所有的值。

wztqucjr

wztqucjr1#

最快的方法是不去做,不要在Map中寻找 * 值 *,而要在Map中寻找 * 键 *。
如果需要搜索 value,请使用另一个数据结构(或单独的Map)。
在map中搜索 value 的唯一方法是线性的(O(N)),但是由于迭代map数据结构的缓存开销,它甚至比迭代向量还要慢。

cbjzeqam

cbjzeqam2#

除非您拥有非常大的数据集(超过100,000次左右)访问Map的时间应该不会困扰你,因为它在任何情况下都是非常小的,因为你已经把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();
}
lfapxunr

lfapxunr3#

可以使用find方法查找和元素,Map通常由red-black trees实现,它具有对数搜索复杂度。
如果需要按值搜索,则可以创建一个反向Map,该Map将初始Map的值作为键,而相应的键就是值。可以在第二个Map中按键搜索值,这将生成键。但是,重建反向Map需要占用时间和存储资源,因此只有在要进行多次搜索时才应这样做。

shstlldc

shstlldc4#

对于值,map与列表或向量没有什么不同,因此穷举(线性)搜索是最快的方法。

vsdwdz23

vsdwdz235#

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

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

这样,您可以只使用值作为向量中的键(索引),并在与nullptr比较之后使用该指针直接访问Map内容。
最大的缺点是当你从map中移除键时需要额外的簿记。如果移除操作足够频繁,你也可以使用map来代替它,因为如果期望的值范围太大(像所有的32位),它就不是内存有效的。
你也可以使用Map迭代搜索作为直接Map缓存的后备存储(它对于整数键(这里的值)工作最快)。所有的缓存命中都将以一个&的位操作为代价,比如8191,4095等(O(1))。所有的缓存未命中仍然需要对Map元素进行一次完整的迭代,这是很慢的(O(N))。
因此,如果缓存命中率接近100%,它可以接近O(1),否则它将是慢的O(N)。

相关问题