【发布时间】:2018-07-11 06:55:42
【问题描述】:
我想实现一个元素数量永远不会超过某个限制L 的地图。插入L+1-th 元素时,应从映射中删除最旧的条目以清空空间。
我发现了类似的东西:Data Structure for Queue using Map Implementations in Java with Size limit of 5。建议使用链接哈希映射,即哈希映射还保留所有元素的链接列表。不幸的是,那是针对 java 的,我需要一个针对 C++ 的解决方案。我在标准库和 boost 库中都找不到类似的东西。
同样的故事:Add and remove from MAP with limited size
这里给出了一个可能的 C++ 解决方案,但它没有解决我下面的问题:C++ how to mix a map with a circular buffer?
我会以与那里描述的非常相似的方式实现它。用于存储键值对的哈希映射和用于保存条目索引的键的链表或双端队列。要插入一个新值,我会将其添加到哈希映射及其索引末尾的键中;如果此时 has 的大小超过限制,我将弹出索引的第一个元素并从 has 中删除具有该键的条目。简单,与添加到哈希映射相同的复杂性。
删除条目需要对索引进行迭代以从那里删除键,这对于链表和双端队列都具有线性复杂性。 (双端队列也有一个缺点,即移除一个元素本身就具有线性复杂性。)所以看起来对这种数据结构的移除操作并没有保留复杂性,因为底层具有映射。
问题是:是否有必要增加复杂性,或者有一些巧妙的方法来实现有限的地图数据结构,以便插入和移除都保持相同的复杂性?
糟糕,刚刚发布并立即意识到一些重要的事情。索引的大小也是有限的。如果这个限制是恒定的,那么迭代它的复杂度也可以被认为是恒定的。
好吧,这个限制给出了移除操作成本的上限。
如果限制非常高,人们可能仍然更喜欢不涉及对索引进行线性迭代的解决方案。
【问题讨论】:
-
所以你只需要一个额外的数据结构,平均在恒定时间内将一个键映射到一个迭代器到链表中?
-
我认为你可以这样做:
using Age = int;你有第一张地图:std::map<K, std::pair<Age,V>>(或unordered_map,你喜欢),还有第二张地图:std::map<Age, I>其中@ 987654330@。年龄计数器初始化为 0,在插入元素时递增,并且元素使用该年龄。然后你有 O(log n) 的插入和删除 -
听起来像是 boost::multi_index 的工作?
-
每个容器都有权衡。您不能对所有操作都具有 o(1) 复杂性。如果有办法,那将是我们唯一需要的容器。
标签: c++ memory data-structures hashmap limit