我想实现一个映射,该映射的元素数量不得超过特定限制L
。当插入第L+1
个元素时,应从地图中删除最旧的条目以清空空间。
我发现了类似的内容: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中删除带有该键的条目。与添加到哈希映射表一样简单,复杂。
删除条目需要在索引上进行迭代才能从此处删除键,这对于链接列表和双端队列都具有线性复杂性。 (双端队列还具有删除元素本身具有线性复杂性的缺点。)因此,看来对此类数据结构的删除操作不会保留复杂性,因为底层具有映射。< / p>
问题是:是否需要增加复杂性,还是有一些聪明的方法来实现有限的地图数据结构,以便插入和删除都保持相同的复杂性?
糟糕,刚发布并立即意识到一些重要的事情。索引的大小也受到限制。如果该限制是恒定的,则也可以将其迭代的复杂性视为恒定的。
好吧,此限制为移除操作的费用提供了上限。
如果限制非常高,您可能仍希望使用不涉及线性迭代而不是索引的解决方案。
答案 0 :(得分:1)
我仍将使用关联容器进行直接访问,并使用顺序访问容器以便轻松删除较旧的项目。让我们看一下所需的访问方法:
push_back
,并简单地添加到关联容器中front
将提供该元素,而pop_front
和erase
将删除它,只要密钥包含在序列容器中 list
允许在恒定的时间内删除元素,前提是您具有迭代器。好消息是,在列表中删除或插入元素不会使指向其他元素的迭代器无效。由于您对保持键的排序没有任何要求,因此我将unordered_map
用于关联容器,并将list
用于序列1。附加要求是list
必须包含密钥,并且unordered_map
必须包含对list
中其对应元素的迭代器。该值可以在两个容器中。因为我假设主要访问权限将是直接访问权限,所以我会将值存储在地图中。
它归结为:
list<K>
以允许识别最早的密钥unordered_map<K, pair<V, list<K>::iterator>>
它将密钥的存储空间增加一倍,并添加一个附加的迭代器。但是键应该不会太大,list::iterator
通常只包含一个指针:这会为速度改变少量内存。
这足以提供恒定的时间
答案 1 :(得分:0)
您可能想看看Boost.MultiIndex MRU example。