[英]Container that does not invalidate iterators (and pointers)
我目前正在寻找提供一些插入(insert或push_back)和一些删除(erase,pop_back不足)方法的容器,并且在调用这两种方法时不会使迭代器或指针无效。
更明确地说,我想要一组元素,可以在其中添加元素(我不在乎位置),而在哪里可以删除任何元素(因此我在乎位置)。 另外,我将具有指向特定元素的外部指针,并且如果我从集合中添加或删除元素,我希望它们保持有效。
据我所知,有两个满足我需求的标准容器: set
和list
。 但是,总的来说,我不喜欢将这样的容器用于如此简单的需求。 由于list
在内部涉及指针,并且不能提供对其元素的随机访问,因此我认为这不是一个好选择。 set
可以对其元素进行随机访问,但是还涉及指针,并且随机访问本身并不是在恒定时间内完成的。 我认为与list
, set
将是更好的解决方案,但是我已经考虑了其他问题。
如果一个简单的向量在删除元素时不尝试保持元素连续呢? 当删除此容器中间的元素时,其位置将为空,并且不会发生其他任何事情。 这样,任何迭代器或指针都不会失效。 同样,在添加元素时,容器将搜索一个空位置,如果没有此类孔,则使用简单的push_back
。
显然,由于push_back
可以使用vector
使迭代器无效,因此我将使用deque
作为实现的基础。 我还将使用某种堆栈来跟踪孔的去除情况。 这样,除了满足我的无效需求之外,添加,删除和访问元素的时间也将固定不变。
但是,仍然存在一个问题:在此容器上进行迭代或仅通过索引访问元素时,我们需要考虑漏洞。 这就是问题开始超越优势的地方。
因此,我的问题是:您如何看待我对那个容器的想法? 更重要的是,您将对我的原始问题, set
, list
或其他东西使用什么? 另外,如果您对上一个问题有一个很好的解决方案(在我的容器上反复进行),请随时向我展示。
要求1:插入(插入或推回)和一些删除(擦除,而不仅仅是最后一个元素)
符合条件的候选对象: deque
, forward_list
, list
, map
, multi_map
, set
, multiset
, unordered_map
, unordered_multimap
, unordered_set
, unordered_multiset
和vector
被淘汰的候选者: array
(不insert
或push_back
), queue
, priority_queue
queue
和stack
(不erase
,仅pop
)
要求2:在调用这两个方法时,不会使迭代器或指针无效
multi_map
候选者: forward_list
, list
, map
, multi_map
, set
, multiset
, deque
(迭代器仅在擦除第一个元素时才有效)和vector
(擦除开始后的所有元素) dequeue
(在大多数情况下), unordered_map
, unordered_multimap
, unordered_set
和unordered_multiset
(如果增长需要重新哈希)和vector
(如果增长需要重新分配) 要求3:外部指针应保持有效
与需求2大致相同的结果。但是unordered_map
, unordered_multimap
, unordered_set
和unordered_multiset
可以满足此要求,因为对元素的引用仍然有效。
要求4:随机访问元素
map
和multimap
set
和multiset
没有随机访问权限,但可以使用成员find()
(O(logn))满足它 find()
可以在O(n)中提供解决方法)。 对问题1的回答: set
或list
哪个更好?
这取决于您的其他要求。 在一组中,每个值只能存储一次。 如果您的元素都是唯一的,请选择集合。 如果不是,则最好选择列表或多集。
我不知道您要存储的元素,但是整个元素是搜索参数吗? 还是有钥匙? 在后一种情况下,您真的会去寻找地图。
对问题2的回答:替代容器呢?
我不会选择双端队列来代替。
如果可以预见最大的元素数量,则只需保留足够的容量即可避免重新分配。 (满足要求1、3和4)。 如果您有一个用于表示孔的“空元素”,则也可以满足要求2。在最坏的情况下,您可以选择向量对元素进行存储,并选择一个有效的指示符。
如果无法确定这样的最大值,我宁愿选择一张map
,该map
被证明是灵活的并且可以满足您的所有要求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.