簡體   English   中英

如何使用帶有“外部”鍵的 std::unordered_map

[英]How to use std::unordered_map with 'external' keys

我的目標是編寫一個 class,它的工作原理類似於 unordered_map,但保持元素的插入順序,同時仍允許通過鍵進行 O(1) 查找。

我的方法如下:

// like unordered_map but keeps the order of the elements for iteration
// implemented as a vector with a unordered_map for constant time lookups
// consider if element removal is needed, since it is O(N) because of the use of a vector of elements
template <typename KEY, typename VAL>
struct ordered_map {
    struct KeyValue {
        KEY key;
        VAL value;
    };

    std::vector<KeyValue> elements; // KeyValue pairs in order of insertion to allow iteration
    std::unordered_map<KEY, int> indexmap; // key -> index map to allow O(1) lookup, is there a way to avoid the redundant key?
    
    //...
}

但是我有一個問題,在我的方法中,我想使用“外部”存儲到它的鍵(在基於映射中的索引值的元素向量中)來查找索引映射。

例如std::sort允許傳入一個比較器,但 unordered_sap 似乎沒有任何類似的東西。

我真的無法在網上找到有關如何完成此操作的任何信息,但我可能會使用錯誤的術語進行搜索。

stl 完全支持這種方法嗎?

或者我是否需要兩次存儲 Key ,我想避免這種情況,因為鍵可以是堆對象,例如 std::strings 。

編輯: unordered_map 而不是 unordered_set 不起作用

我的目標是編寫一個 class 像 unordered_map 一樣工作,但保持元素的插入順序,同時仍然允許通過鍵進行 O(1) 查找

...並且無需復制密鑰,以防萬一它很大和/或很昂貴。

所以,你想要兩件事:

  1. 具有與std::unordered_map相同語義的常量時間關聯查找(沒有重復的鍵,或者您會/應該要求std::unordered_multimap
  2. 順序索引跟蹤插入順序

您已選擇使用順序容器實現關聯查找,並使用關聯容器實現順序索引。 我不知道為什么,但讓我們嘗試更自然的選擇:

  1. 關聯查找應該只是std::unordered_map<Key, SomeValueType>
  2. 順序索引可以只是std::vector<SomeValueType*>

剩下的空白是SomeValueType :它可能只是VAL ,但是每當我們刪除某些東西時,我們都需要做額外的工作來修復順序索引。 我們可以改為std::pair<VAL, size_t> ,這樣它就可以存儲我們需要在擦除時刪除的迭代器的索引i 不利的一面是,除了將所有i+1..N個向量元素向下移動一個之外,我們需要更新每個 map 元素的索引值。

如果要保留恆定時間擦除,則可能需要將順序索引設為std::list<SomeValueType*> ,並在 map 元素中保留std::list::iterator 鏈表上的實際線性迭代會比向量慢,但在擦除元素時會得到相同的復雜性。


注意。 順序索引確實需要存儲指針而不是迭代器——我最初忘記了無序映射的失效行為。 但是,如果您想訪問密鑰,它們顯然可以是std::unordered_map<key, SomeValueType>::value_type指針......我只是寫出了較短的替代方案。

暫無
暫無

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

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