顺序容器操作
每种顺序容器都提供了一组类型定义和以下操作:
1、添加元素
2、删除元素
3、设置容器大小
4、获取容器内第一个元素和最后一个元素(如果有的话)
容器定义的类型
1、size_type:无符号整形,定义了容器的长度
例子:size_type st=ivec.size();//ivec是一个容器
2、iterator:容器的迭代器(顺序)
例子:vector<int>::iterator iter;
3、const_iterator:元素的只读迭代器(顺序)。其指向的元素,无法修改其值。
例子:vector<int>::const_iterator citer;
4、reverse_iterator:逆序迭代器
例子:vector<int>::reverse_iterator riter;
5、const_reverse_iterator:只读逆序迭代器
例子:vector<int>::const_reverse_iterator criter;
6、different_type:存储两个迭代器差值的无符号整形,可为负数
例子:vector<int>::difference_type dt=iter1-iter2;
7、value_type:容器元素类型
例子:vector<int>::value_type ivt=10;(此例子中等同于int ivt=10;)
8、reference:相当于value_type&,是value_type的引用类型
例子:
vector<int>::value_type a=10;
vector<int>::reference b=a;
b=2;//执行后,a=2,b=2,具体细节看“关于引用类型”一文
9、consr_reference:相当于const value_type&
例子:
vector<int>::value_type a=10;
vector<int>::const_reference b=a;
b=2;.//error:左值是一个常量对象
顺序容器的添加元素操作
1、c.push_back(t):在容器c的尾部添加值为t的元素。返回void
2、c.push_front(t):在容器c的首部添加值为t的元素。返回void。只适用于list和deque
3、c.insert(p,t):在迭代器p所指向的元素前插入值为t的新元素。返回指向新元素的迭代器
4、c.insert(p,n,t):在迭代器p所指向的元素前插入n个值为t的新元素。返回void
5、c.insert(p,b,e):在迭代器p所指向的元素前插入迭代器b和e组成的范围内的元素。返回void(b和e组成的范围为左闭合区间)
关系操作符
所有的容器类型都支持关系操作符来实现两个容器的比较。
1、参与比较的容器必须具有相同的容器类型,并且元素类型也必须相等。
2、容器的比较是基于元素的比较。如元素类型不提供比较操作,则容器也无法进行比较操作。
考虑以下的例子:
ivec1:1 3 5 7 9 12
ivec2:0 2 4 6 8 10 12
ivec3:1 3 9
ivec4:1 3 5 7
ivec5:1 3 5 7 9 12
分析如下结果:
ivec1>ivec2:比较第一个不等的元素,显然,1大于0,所以ivec1>ivec2。
ivec3>ivec1:前两个元素相等,比较第三个元素,显然9大于5,所以ivec3>ivec1。
ivec4<ivec1:前4个元素相等,但ivec的元素数量少于ivec1,所以,ivec1>ivec4。
ivec1=ivec5:所有元素相等,并且长度相等。
ivec1!=ivec4:虽然ivec4的元素和ivec1的前4个元素相等,但长度不等。
总结:
容器的比较是基于元素的。顺序比较容器内的元素,如不等,则当前元素大小决定了容器的大小;如相等,则比较下一个。如全部相等,且长度相等,则两容器相等。否则不等。
容器大小的操作
所有的容器都提供如下几种操作,与容器容量相关:
1、c.size():返回容器中的元素个数。返回类型为c::size_type.
2、c.max_size():返回容器中可容纳的最多元素个数,返回类型为c::size_type.
3、c.empty():判断容器大小是否为0,如为0,返回真,否则返回假
4、c.resize(n):调整容器c的长度大小,使其能容纳n个元素。如果n<c.size(),则删除多出来的元素;否则,添加采用值初始化的新元素。
5、c.resize(n,t):调整容器c的大小,使其能容纳n个元素。所有新添加的元素值都为t。
例如:
list<string> slit;
slit.resize(10,"hahaha");//将slit的长度调整为10个元素,新添加的元素值全部置为"hahaha"
slit.resize(10); //将slit的长度调整为10个元素,新添加的元素值全部置为""(采用string的初始化)
注意:
使用resize操作时,有可能使迭代器失效。对于压缩容器,则指向被删除元素的迭代器都失效。
访问元素操作
如果容器非空,则有以下几种访问元素的操作。
1、c.back():返回容器c的最后一个元素的引用。c不可为空
2、c.front():返回容器c的首元素的引用。c不可为空
3、c[n]:返回下标为n的元素的引用。n不可小于0或大于c.size()。
4、c.at[n]:返回下标为n的元素的引用。n不可越界。如越界,at函数跑出out_of_range异常
注:3、4只适用于vector和deque容器。
考虑下面一个例子:
if(!ilist.empty())
{
//获取首元素
list<int>::reference val=*ilist.begin();
list<int>::reference val2=ilist.front();
//获取尾元素
list<int>::reference last=*(--ilist.end());
list<int>::reference last2=ilist.back();
}
删除元素操作
1、c.erase(p):删除迭代器p所指向的元素。返回指向被删除元素的后一个元素的迭代器。p不可指向容器超出末端的下一位置。
2、c.erase(b,e):删除迭代器b和e所标记的范围内所有元素(左闭合区间)。返回一个迭代器,指向被删除元素段的后一个元素。如e是指向容器超出末端的下一位置,则返回容器超出末端的下一位置。
3、c.clear():删除容器c内的所有元素。返回void。
4、c.pop_back():删除容器c的最后一个元素。c不可为空容器。
5、c.pop_front():删除容器c的第一个元素,返回void。c不可为空容器。只适用于list和deque。
注:erase、pop_back、pop_front会使指向被删除元素的迭代器失效。对于vector容器,指向删除点后的元素的迭代器通常也会失效。
赋值与交换元素swap
1、c1=c2:删除容器c1的所有元素,然后将c2的元素复制给c1。c1个c2的类型(包括容器类型和元素类型)必须相同。
2、c1.swap(c2):交换c1和c2的内容。c1和c2的类型必须相同。该函数的执行速度通常要比将c2复制给c1快。
3、c.assign(b,e):重新设置c的元素,将迭代器b和e标记的范围内所有元素复制到c中。b和e必须不是指向c中元素的迭代器。
4、cassign(n,t):将容器c重新设置为存储n个值为t的元素。
注:swap不会删除和插入任何元素,而且容器内没有移动任何元素,因此迭代器不会失效。例如,原先指向ivec1[1]的迭代器,当ivec1和ivec2交换后,该迭代器指向ivec2[1]。