我目前正在寻找提供一些插入(insert或push_back)的容器以及一些删除(erase,pop_back是不够的)方法,并且在调用这两种方法时不会使迭代器和指针无效。
更清楚的是,我想要一组元素,我可以在其中添加一个元素(我不关心在哪里),以及我可以删除任何元素的地方(所以我关心在哪里)。另外,我会有指向特定元素的外部指针,如果我在集合中添加或删除元素,我希望它们保持有效。
据我所知,有两个满足我需求的标准容器:set
和list
。但是,一般来说,我不喜欢将这种容器用于这种简单的需求。由于list
内部涉及指针,并且不提供对其元素的随机访问,我认为这不是一个好的选择。 set
可以随机访问其元素,但也涉及指针,随机访问本身不是在恒定时间内完成的。我认为set
比list
更好的解决方案,但我已经考虑了其他事情。
一个简单的向量怎么样,当一个元素被删除时,它不会试图保持元素连续?删除此容器中间的元素时,其位置将为空,并且不会发生任何其他情况。这样,就不会使迭代器或指针失效。此外,在添加元素时,容器会搜索空位置,如果没有这样的洞,则使用简单的push_back
。
显然,由于push_back
可以使vector
的迭代器无效,我会使用deque
作为实现的基础。我还会使用某种堆栈来跟踪删除元素的漏洞。这样,添加,删除和访问元素将在恒定时间内完成,此外还满足我的无效请求。
然而,仍有一个问题:当迭代这个容器或只是通过索引访问元素时,我们需要考虑漏洞。这就是问题开始超越优势的地方。
因此我的问题是:您如何看待我对该容器的想法?
更重要的是,您会对我的原始问题使用什么,set
,list
或其他什么?
另外,如果您对上一个问题(迭代我的容器)有一个很好的干净解决方案,请随时给我看。
答案 0 :(得分:3)
要求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
和stack
(否{{ 1}},仅erase
)
要求2:在调用这两种方法时不会使迭代器或指针无效
pop
,forward_list
,list
,map
,multi_map
,set
,multiset
(迭代器仅在擦除第一个元素时仍然有效)和deque
(擦除开始后的所有元素)vector
(在大多数情况下),dequeue
,unordered_map
,unordered_multimap
和unordered_set
(如果增长需要rehash)和unordered_multiset
(如果增长需要重新分配)要求3:外部指针仍然有效
与要求2大致相同的结果。但vector
,unordered_map
,unordered_multimap
和unordered_set
会满足此要求,因为对元素的引用仍然有效。
要求4:随机访问元素
unordered_multiset
和map
multimap
和set
没有随机访问权限,但可以使用成员multiset
(O(logn))find()
可以在O(n)中提供变通方法)。 回答问题1:哪个更好,find()
或set
?
这取决于您的其他要求。在一个集合中,每个值只能存储一次。如果您的元素都是唯一的,请选择该集。如果不是,您最好选择列表或多重集。
我不知道你要存储的元素,但搜索参数的整个元素是什么?还是有钥匙?在后一种情况下,你真的去寻找一张地图。
回答问题2:替代容器怎么样?
我不会为你的替代品选择deque。
如果您可以预见元素的最大数量,您可以简单地保留足够的容量以避免重新分配。 (满足要求1,3和4)。 如果你有一个"空元素"为了表示漏洞,你也可以满足要求2.在最坏的情况下,你可以选择一个矢量来分析你的元素和一个指示符是否有效。
如果这样的最大值无法确定,我宁愿选择list
来证明其灵活性并满足您的所有要求。