容器vector:
1.vector的能力:
vector使用动态数组实现的,所以元素之间总是存在某种顺序,所以vectors是一种有序群集。vector支持随机存取,因此只要知道位置,你可以在常数时间内存取任何元素。
在末端附加或删除元素时,vector的性能相当好,可是如果你在前端或中部安插或删除元素,性能就不怎么样了,因为操作点之后的每个元素都必须移到另一个位置,而每一次移动都得调用赋值操作符。
2.大小和容量:
vector操作大小函数:
size() 返回容器中的元素数量
empty() 判断容器是否为空(相当于size()==0,但可能但可能更快)
max_size() 返回元素的最大可能数量
例子:
#include<iostream>
#include<vector>
using namespace std;
void main()
{
vector<int> v;
for(inti=0;i<5;i++)
{
v.push_back(i);
}
cout<<"size:"<<v.size()<<endl;
cout<<"max_size:"<<v.max_size()<<endl;
}
运行结果:
size:5
max_size:1073741823
size()函数返回v的元素数量
max_size()函数返回的v容器可能存放的最大元素个数
另外一个与大小有关的函数是capacity(),它返回vector实际能够容纳的元素数量。如果超越这个数量,vector就有必要重新配置内部存储器(重新分配大小)。
vector的容量之所以很重要,有以下两个原因:
1. 一旦内存重新配置,和vector元素相关的所有引用、指针、迭代器都会失效。
2. 内存重新配置很消耗时间。
你可以使用reserve()保留适当容量,避免一再重新配置内存。如此一来,只要保留的容量尚有余裕,就不必担心引用失效。
std::vector<int> v;
v.reserve(80);
另一种避免重新配置内存的方法是,初始化期间就向构造函数传递附加参数,构造出足够的空间。如果你的参数是个数值,它将成为vector的起始大小。
std::vector<T> v(5);
注意:vector不能使用reserve()来缩减容量。如果调用reserve()所给的参数比当前vector的容量还小,不会引发任何反应。
vector的操作函数:
1.构造、拷贝和析构:
vector<Elem> c 产生一个空vector,其中没有任何元素
vector<Elem> c1(c2) 产生另一同型vector副本(所有元素都被拷贝)
vector<Elem> c(n) 利用元素的缺省构造函数生成一个大小为n的vector
vector<Elem>c(beg, end) 产生一个vector,以区间[beg,end]做为元素值
c.~vector<Elem> 销毁所有元素,并释放内存
3. vector支持判断运算符,==、!=、<、>、<=、>=
4. 赋值
c1 = c2 将c2的全部元素赋值为c1
c.assign(n,elem); 复制n个elem,赋值为c
c.assign(beg ,end); 将区间[beg,end]内的元素赋值为c
c.swap(c2) 将c1和c2元素互换
swap(c1,c2); 同上,此为全局函数
5. 元素存取:
c.at(idx) 返回索引idx所标示的元素。如果idx越界,抛出out_of_range
c[idx] 返回索引idx所标示的元素。不进行范围检查
c.front() 返回第一个元素。不检查第一个元素是否存在
c.back() 返回最后一个元素。不检查最后一个元素是否存在
注:调用operator[]时,你必须心里有数,确定索引有效;调用front()、back()时必须确定容器不为空:
例子:
std::vector<Elem>coll; //empty
coll[5]=elem; //error
std::cout<<coll.front(); //error
//不会抛出异常,因为不检查
正确方法:
std::vector<Elem>coll; //empty
if(coll.size()>5)
{
coll[5]=elem; //ok
}
if(!coll.empty())
{
cout<<coll.front(); //ok
}
coll.at(5)=elem; //ok throws out_of_range exception
6. 迭代器相关函数
c.begin() 返回一个随机迭代器,指向第一个元素
c.end() 返回一个随机迭代器,指向最后元素的下一个位置
c.rbegin() 返回一个逆向迭代器,指向逆向迭代器的第一个元素(最后一个元素)
c.rend() 返回一个逆向迭代器,指向逆向迭代器的最后元素的下一个位置(第一元素的前一个位置)
7. 安插和移除元素:
安插元素和移除元素,都会使得‘作用点’之后的元素的引用、指针、迭代器失效。如果安插操作甚至引发内存重新分配,那么该容器身上的所有引用、指针、迭代器都会失效。
c.insert(pos ,elem); 在pos位置上插入一个elem副本,并返回新元素位置
c.insert(pos ,n,elem); 在pos位置上插入n个elem副本。无返回值
c.insert(pos,beg,end); 在pos位置上插入区间[beg,end]内的所有元素的副本。无返回值
c.push_back(elem); 在尾部添加一个elem副本
c.pop_back(); 移除最后一个元素
c.erase(pos); 移除pos位置上的元素,返回下一个元素的位置
c.erase(beg,end); 移除[beg , end] 区间内的所有元素,返回下一个元素的位置
c.resize(num); 将元素数量改为num(如果size()变大了,多出来的新元素都需要以缺省构造函数构造)
c.resize(num,elem);将元素数量改为num(如果size()变大了,多出来的新元素都为elem)
c.clear() 移除所有元素,将容器清空
vector没有提供任何函数可以直接移除与某值相等的元素
以下语句将其值为val的元素移除:
std::vector<Elem> coll;
……
std::vector<Elem>::iterator pos;
pos =find(coll.begin() , coll.end() , val);
if(pos!=coll.end())
{
coll.erase(pos);
}