簡體   English   中英

std :: unordered_map中的鍵與哈希

[英]key vs. hash in a std::unordered_map

我經常需要一個將哈希與任意對象相關聯的容器(理論上,如果兩個不同的對象具有相同的哈希,則可能發生沖突)。

在C ++ 98中,我將使用template<class Key, class T> class std::map使用Key作為在T計算的哈希值:

struct object;
typedef std::string object_hash;

object_hash compute_hash(const object& obj);

std::map<object_hash, object> hash_map;

object_hash insert_or_assign(const object& obj)
{
    object_hash hash = compute_hash(obj);
    hash_map[hash] = obj;
    return hash;
}

std::pair<bool, object> get_at(const object_hash& hash)
{
    std::map<object_hash, object>::iterator iter = hash_map.find(hash);
    if( iter == hash_map.end() )
        return std::pair<bool, object>(false, object());
    else
        return std::pair<bool, object>(true, iter->second);
}

但是從C ++ 11開始,我們已經對容器進行了哈希處理,所以我期望這樣的東西:

template<class T, class Key = std::hash<T>> class std::hashed_map

要求為類型T提供自定義std::hash ,但是我們有

template<class Key, class T, class Hash = std::hash<Key>> class unordered_map

這不適用於我的情況,其中鍵是哈希本身,並且沒有與該任意對象相關的其他“鍵”概念。

與我預期的類似:

template<class Key, class Hash = std::hash<Key>> class unordered_set

但是沒有基於哈希的查找功能。

在現代C ++中,是否存在使用哈希的內置容器,並具有基於這些哈希的查找接口?

您有一個映射而不是一個哈希映射; 您的密鑰是哈希的事實與容器無關。

關於唯一的顯着特征是您很少在乎哈希的順序。 因此無序地圖可能是最好的。

使用舊的解決方案,將地圖替換為無序地圖,將equal運算符替換為less操作,然后將哈希值(可能向下)替換為64位。 例如,經典的指針哈希只是reinterpret_cast<unit_ptr>( key )

最初, unordered_map稱為hash_map ,然后ISO C ++委員會明智地將其重命名,因為std::mapstd::unordered_map之間的重要區別不是前者使用二叉樹而后者使用哈希, 而是前者是有序的而后者保證了恆定的時間復雜度。

因此, std::unordered_map內部使用哈希的事實只不過是實現細節:如果是自定義類型(並且鍵很少是自定義類型),則只需要提供std::hash特殊化即可。 除此之外,您應該忘記此容器的內部哈希。

盡管有一些評論,但是如果您的鍵是哈希,那么C ++ 98實現絕對沒有錯。 您可以繼續在C ++> = 11中使用它,並在可能的情況下將其更新和使用新的語言工具。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM