这篇记录下容器的知识:
C++标准库中的容器大概分为:顺序容器和关联容器。
容器元素要求:复制和赋值(IO对象就不行)
顺序容器有:vector、list、deque、stack、queue、priority_queue。
stack、queue是用deque实现的,priority_queue支持随机访问,所以是用vector实现的。
关于vector、list和java中有些区别。
vector更像java中的list,容器中元素连续存放,可以通过索引访问元素(既可以随机访问容器中的某一个元素)。插入删除越靠前代价越高。
而C++中的list有点像java中的linkedlist,不支持随机访问,需要遍历访问,但是插入、删除很快。
而deque又有vector与list的一些特点。能快速随机的访问,插入caozuo.html" target="_blank">删除操作在首部或尾部效率不错。
但是vector做了一些优化,在初始化容器的时候,容器的容量一般都大于容器元素的个数,这样可以防止容器扩容带来的开销(复制元素、清除以前容器、开辟新空间)。
这些容器也都定义了自己的迭代器,begin()\rbegin()、end()\rend()这可以表示一个容器的迭代器范围,list因为不能随机访问,所以迭代器不支持比较和算术运算。
插入元素:insert(插入一个元素,就返回该元素的迭代器,否则为void),push_back,push_front(list、deque),push_返回void
删除元素:erase(返回下一个元素,如果删除元素不存在就会出错),clear,pop_back,pop_front(list、deque),pop_返回void
访问元素:front、back、下标或者at(下标),下标操作只使用于vector、deque。如果没有改元素,这些访问都将出错。
如果元素不存在进行访问或者删除一般会出错。所以在访问或者删除前,应该进行查询,使用find方法,如果不存在就返回end迭代器。
赋值:
swap代价最小(感觉只是名字变了),支持=号复制,assign是先删除再添加,支持一个迭代器范围或者n个相同元素作为参数。如果不同容器元素类型不同但是兼容,就可以使用assign函数。
容器容量:size,max_size(1073741823),resize,capacity、revserve(大于等于size)。
关联容器:map、set、multimap、multiset
首先容器中元素为pair<T1,T2>类型,这和java中的Entity比较像。有构造方法,也有make_pair方法构造。
T1就为pair.first,T2为pair.second。
map为K-V,K必须定义((默认)使用<来比较);自身比较为false,相互不小于就为相等。
有几个属性:key_type键的类型,mapped_type值的类型,value_type为pair类型<const key_type, mapped_type>这个和java又有些差别。
map支持下标访问,如果不存在就添加,也支持insert插入操作,如果K存在就不改变map这个和java中的put有些差别,并且插入单个元素则返回:
pair<map<K,V>::iterator, bool> bool表示是否成功,pair的T1表示插入元素的pair类型。插入多个元素返回void。
map元素的查找:count(K),find(K),find如果没找到返回end迭代器。
map删除操作:erase(K)返回size_type表示删除元素个数。
如果使用erase删除一个迭代器,那么这个迭代器必须在容器中,不能为end,返回void。
set只有key的集合,value_type与key_type一样。
添加删除和map操作类似,key都是唯一,不能修改。
multimap、multiset支持K对应多个实例。
multimap中同一个key的多个实例会相邻存放,count返回大于1,find指向第一个关联元素的迭代器。
为了更好的操作,容器还提供了lower_bound(K)和upper_bound(K)表示同一个key的多个实例的边界迭代器[),也提供了一个整合迭代器equal_range,存放的是pair对象,second为upper_bound(K),first为lower_bound(K)。
另外string也可以被看成是一个容器,它额外支持下标插入方法,substr,append,replace以及众多的find方法。
最后关于迭代器失效,这个和java中很相似,java中对一个产生迭代器的集合做增加删除修改会出现modifyException。C++中也会有相似的情况,比如对一个vector做添加处理,添加元素之后所有的迭代器都会失效。迭代器失效就不能再使用,如果再次使用可能会导致与悬垂指针类似的错误。(悬垂指针:指向对象清除,但是指针仍指向原地址)
?