STL结构:“如果不存在则插入”操作?

时间:2015-10-06 15:33:08

标签: c++ optimization data-structures stl unordered-map

我正在研究一个正在处理一些指数时间算法的程序。因此,我的程序的主循环正在运行多次,我正在尝试尽可能地优化它。

分析显示大部分时间花在std::unordered_map的查找和哈希计算上。

我想知道:

  1. 有没有办法缓存std::unordered_map的密钥的哈希值,然后将其作为参数提供,以便稍后插入?

  2. 我是否有办法在一次操作中执行以下操作:给定一个键和值{x,y},检查键x是否在地图中,如果不是,插入并返回{x,y},否则返回{x,z}表示地图中已有的z

  3. 我现在正在做这样的事情,但效率很低,因为我必须计算密钥的哈希并检查它是否在地图中。但如果它不在地图中,我会进行完全独立的插入操作。从理论上讲,检查地图中是否存在该地图应该可以找到插入地图时的位置。

    我愿意尝试其他数据结构,例如std::map或来自Boost的东西,如果它们会减少此操作的时间。

3 个答案:

答案 0 :(得分:3)

您可以使用std::unordered_map::insert()的返回值来实现密钥存在检查+使用单个哈希计算进行插入。

template<typename K, typename V>
std::pair<K, V> myinsert(std::unordered_map<K, V> &map, const std::pair<K, V> &kv)
{
    return *(map.insert(kv).first);
}

答案 1 :(得分:0)

你不能缓存密钥的哈希值,但是如果你有一个迭代器到上次的位置(从你最初插入的时候,或者你最后一次成功找到该项目),你可以使用insert( const_iterator hint, value_type&& value );成员,它还有助于将迭代器返回到新插入的元素或阻止插入的先前存在的元素。

答案 2 :(得分:0)

您可以只使用std::map::emplace()

仅在容器中没有其他元素具有与要插入的键相同的键的情况下插入该操作(地图容器中的键是唯一的)。

示例

#include <iostream>
#include <utility>
#include <string>
#include <map>

typedef std::map<std::string, std::string> StringMap; 
typedef std::pair<StringMap::iterator, bool> PairKey;

int main()
{
    std::map<std::string, std::string> m;

    // uses pair's template constructor
    m.emplace("a", "aaa");
    m.emplace("b", "bbb");
    m.emplace("d", "ddd");

    PairKey pair = m.emplace("d", "dddddd");

    if (pair.second == false)
        std::cout<< "d was existed so value didn't change" << std::endl;
    
    std::cout<<"-------MAP_LIST------" << std::endl;
    for (const auto &p : m)
       std::cout << p.first << " => " << p.second << '\n';
    std::cout<<"-------========------" << std::endl;
}

输出:

d was existed so value didn't change
-------MAP_LIST------
a => aaa
b => bbb
d => ddd
-------========------