我很想知道一个类似队列的容器,但它具有密钥访问权限,就像地图一样。 我的目标很简单:我想要一个FIFO队列,但是,如果我插入一个元素并且一个给定键的元素已经在队列中,我希望它的新元素替换已经在队列。例如,按插入时间排序的地图将起作用。
如果没有这样的容器,你认为它可以通过同时使用队列和地图来实现吗?
答案 0 :(得分:3)
Boost multi-index提供了这种容器。
为了自己实现它,我可能会选择map
,其值由链表节点和有效负载组成。列表节点可以手动滚动,也可以是Boost intrusive。
请注意,queue
适配器的要点是隐藏Sequence的大部分接口,但是你想要隐藏它隐藏的细节。所以我认为你的目标应该是重现queue
的界面(稍微修改一下push
的改变的语义)而不是实际使用它。
答案 1 :(得分:1)
显然,您可以使用类似队列的容器完成所需的操作,但是您必须在每次插入时花费O(n)
时间来确定元素是否已存在。如果您基于类似std::vector
的内容实施队列,则可以使用二进制搜索,并基本上加快插入O(log n)
(当内存重新分配时仍需要O(n)
操作完成了。
如果这很好,只需坚持下去。带有额外容器的变体可能会提升性能,但是如果第一个解决方案足够,它也可能容易出错。 ,只需使用它。
在第二种情况下,您可能希望将元素存储在不同的容器中两次 - 原始队列和类似地图(或者有时 hashmap 可能表现更好)。该映射仅用于确定元素是否已存在于容器中 - 如果是,则必须在队列中更新它。
基本上,这给我们O(1)
哈希映射查找的复杂性(在现实世界中,由于冲突,这可能会变得更加丑陋 - 哈希映射对确定元素存在不是很好)和{{ 1}}在不需要更新的情况下插入时间,并且需要O(1)
案例更新的插入时间。
根据实际更新操作的百分比,实际插入性能可能会从O(n)
变为O(1)
,但如果更新的数量足够小,此方案肯定会胜过第一个。
但是,您必须同时将元素插入两个容器中,如果元素被删除则应该完成同样的操作,我会三思而后行“我真的需要提升性能吗?”。 < / p>
答案 2 :(得分:0)
我通过队列和可选的地图看到了简单的方法。
为元素定义某种==运算符。
然后只需要一个队列并在每次要插入时搜索元素。
您可以通过将元素位置映射到元素而不是每次都搜索队列来优化它。