在哪种情况下,我使用特定的STL容器?
我一直在阅读关于C ++的STL容器,特别是关于STL及其容器的部分。 现在我明白每一个人都有自己的特定属性,而且我已经接近了记住他们所有的人……但是我还没有把握的是在哪种情况下他们都被使用了。
什么是解释? 示例代码非常喜欢。
这个备忘单提供了不同容器的相当好的总结。
请参阅底部的stream程图,作为在不同的使用场景中使用的指南:
由David Moore创build并授权CC BY-SA 3.0
下面是一个由David Moore创build的版本(见上)所启发的stream程图,它是最新的(主要是)新标准(C ++ 11)。 这只是我个人的看法,这不是无可争议的,但我认为这可能是有价值的这个讨论:
简单的答案:使用vector<>的一切,除非你有一个真正的理由否则。
当你发现一个你正在思考的情况时,“Gee,vector <>在这里因为X而不能很好地工作”,那么在X的基础上进行。
请看Scott Meyers的有效STL。 很好的解释如何使用STL。
如果你想存储一个确定/未定数量的对象,你永远不会删除任何,那么一个向量就是你想要的。 这是C数组的默认replace,它像一个工作,但不会溢出。 你可以预先设置它的大小以及reserve()。
如果你想存储不确定数量的对象,但是你将会添加它们并删除它们,那么你可能需要一个列表…因为你可以删除一个元素而不用移动任何后续的元素 – 不像vector。 但是,它比一个向量需要更多的内存,而且你不能顺序访问一个元素。
如果你想要一堆元素,只find这些元素的独特价值,把它们全部读入一个集合就可以了,它也会为你分类。
如果你有很多的键值对,你想按键sorting,那么地图是有用的,但它只能保存每个键的一个值。 如果每个键需要多个值,则可以在地图中使用vector/列表作为值,或者使用多图。
它不在STL中,而是在STL的TR1更新中:如果有很多键 – 值对要按键查找,并且不关心它们的顺序,那么可以想要使用散列 – 这是tr1 :: unordered_map。 我用它与Visual C ++ 7.1,它被称为stdext :: hash_map。 它有一个查找O(1),而不是O(log n)查找映射。
这一切都取决于你想要存储什么,以及你想要对容器做什么。 以下是我倾向于使用最多的容器类的一些(非常详尽的)示例:
vector
:紧凑的布局,每个包含的对象很less或没有内存开销。 有效地迭代。 追加,插入和擦除可能是昂贵的,特别是对于复杂的对象。 很便宜的find一个包含对象索引,例如myVector [10]。 使用你在C中使用数组的地方。很好的地方,你有很多简单的对象(例如int)。 在将大量对象添加到容器之前,不要忘记使用reserve()
。
list
:每个包含对象的内存开销很小。 有效地迭代。 追加,插入和擦除都很便宜。 使用C中的链接列表
set
(和multiset
):每个包含对象的显着内存开销。 如果该容器包含给定的对象,或者有效地合并容器,请使用需要快速查找的位置。
map
(和multimap
):每个包含对象的显着内存开销。 使用您想要存储键值对的位置并快速按键查找值。
zdanbuild议的作弊表上的stream程图提供了一个更详尽的指导。
到目前为止只提到的一个重要的一点是,如果你需要连续的内存(如C数组给出),那么你只能使用vector
, array
或string
。
如果在编译时已知大小,则使用array
。
如果您只需要处理字符types并需要string,而不仅仅是通用容器,则使用string
。
在所有其他情况下使用vector
(在大多数情况下vector
应该是容器的默认select)。
所有这三个你可以使用data()
成员函数来获取指向容器的第一个元素的指针。
我学到的一个教训是:尝试将它包装在一个类中,因为每天改变容器types可以产生很大的惊喜。
class CollectionOfFoo { Collection<Foo*> foos; .. delegate methods specifically }
它不需要花费太多的时间,而且当你想在这个结构上有人做x操作时想要中断的话,可以节省时间。
为工作select完美的数据结构:
每个数据结构提供了一些操作,这可能是不同的时间复杂度:
O(1),O(lg N),O(N)等
你必须做出最好的猜测,在哪个操作上做的最多,并且使用一个具有该操作的数据结构作为O(1)。
简单,不是( – :
我扩展了Mikael Persson的神奇stream程图。 我添加了一些容器类别,数组容器和一些笔记。 如果你想自己的副本, 这是谷歌图纸。 谢谢,Mikael做基础工作! C ++容器select器