STL顺序容器Vector
Vector简介
Vector 容器就像传统C语言里的动态数组一样。Vector将它的所有元素都复制到它内部的动态数组中。这些元素具有一定的相对顺序。所以,vector容器是顺序容器,它支持随机方式访问容器里面的元素。这样你就可以通过迭代器在一个常数的时间里访问到该元素。它的迭代器是随机访问迭代器,因此能够使用STL里面的每一个标准算法。Vector容器在末尾进行插入删除的效率很高,但是在中间进行插入删除操作则效率低下,因为在中间插入删除,就要对插入或者删除位置之后的元素位置进行相应的调整,极端情况下需要移动整个容器里面的元素。
Vector基本操作
size and capacity
Vector表现良好的一个原因就是它总是分配足够多的内存来让你存放元素。为了更好、更准确的使用vector,我们需要理解它的size和capacity操作。size()返回vector当前的大小,capacity()返回下次再分配内存空间时所需要的最少元素个数,当元素个数超过capacity后vector会再次capaticy分配空间(分配空间大小与编译器有关Linux采用是翻倍,VS采用的策略不是这样)。
非修改性操作:
操作 | 说明 |
---|---|
c.enpty() | 判断容器是否为空,为空返回true |
c.size() | 返回当前容器内元素数量 |
c.max_size() | 返回容器可能保存的最多元素 |
c.capavity() | 返回在下次再分配空间时所能存放元素的最大数量 |
c.reserve(num) | 当空间不够是的时候对capacity进行扩容 |
c.shrink_to_fit() | 将apacity的大小重置为元素的数量(c++11) |
c1==c2 | 判断c1与c2是否相等 |
c1!=c2 | 判断c1与c2是否不等 |
c1>c2 | 判断c1是否大于c2 |
c1 | 判断c1是否小于c2 |
c1>=c2 | 判断c1是否大于等于c2 |
c1<=c2 | 判断c1是否小于等于c2 |
代码示例:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec;
for(int i=0;i<20;i++) {
vec.push_back(i);
cout<<"now capacity is :"<<vec.capacity()<<endl;
}
cout<<"vec size is :"<<vec.size()<<endl;
cout<<"vec maxsize is :"<<vec.max_size()<<endl;
vec.erase(vec.begin()+10,vec.end());
cout<<"after erase vec size is :"<<vec.size()<<endl;
cout<<"after erase capacity is :"<<vec.capacity()<<endl;
//演示c++11中的shrink_to_fit()
vector<int>(vec).swap(vec);
cout<<"after swap vec size is :"<<vec.size()<<endl;
cout<<"after swap capacity is :"<<vec.capacity()<<endl;
for(int i=10;i<20;i++){
vec.push_back(i);
cout<<"now capacity is :"<<vec.capacity()<<endl;
}
vec.erase(vec.begin()+10,vec.end());
vec.shrink_to_fit();
cout<<"after shrink vec size is :"<<vec.size()<<endl;
cout<<"after shrink capacity is :"<<vec.capacity()<<endl;
return 0;
}
输出如下(Linux下):
now capacity is :1
now capacity is :2
now capacity is :4
now capacity is :4
now capacity is :8
now capacity is :8
now capacity is :8
now capacity is :8
now capacity is :16
now capacity is :16
now capacity is :16
now capacity is :16
now capacity is :16
now capacity is :16
now capacity is :16
now capacity is :16
now capacity is :32
now capacity is :32
now capacity is :32
now capacity is :32
vec size is :20
vec maxsize is :4611686018427387903
after erase vec size is :10
after erase capacity is :32
after swap vec size is :10
after swap capacity is :10
now capacity is :20
now capacity is :20
now capacity is :20
赋值操作
操作 | 说明 |
---|---|
c = c2 | 将c2的所有元素赋值给c1 |
c = rv | 将右值rv的所有元素的值移动赋值给c(c++11标准) |
c = {x1,x2,x3} | 使用初始化列表的所有元素赋值给c |
c.assign(n , x) | 用元素x的n个拷贝来初始化c |
c.assign(beg , end) | 用范围[beg,end)内的元素进行赋值 |
c.assign( {x1,x2,x3} ) | 用初始列表来赋值 |
c1.swap(c2) | 交换c1与c2中的数据 |
swap(c1 ,c2) | 交换c1与c2中的数据 |
元素访问操作
操作 | 说明 |
---|---|
c[index] | 返回位于index 位置的元素(不进行范围检查) |
c.at(index) | 返回位于index 位置的元素(进行范围检查,超出范围抛出异常) |
c.front() | 返回第一个元素(不检查该元素是否存在) |
c.back() | 返回最后一个元素(不检查该元素是否存在) |
迭代器
操作 | 说明 |
---|---|
c.begin() | 返回指向第一个元素的iterator |
c.end() | 返回指向最后一个元素的iterator |
c.cbegin() | 返回指向第一个元素的const_iterator |
c.cend() | 返回指向最后一个元素const_iterator |
c.rbegin() | 返回指向逆序第一个元素的iterator |
c.rend() | 返回指向逆序最后一个元素的itreator |
c.crbegin() | 返回指向逆序第一个元素的const_iterator |
c.crend() | 返回指向逆序最后一个元素的const_iterator |
插入、移除等元素修改操作
操作 | 说明 |
---|---|
c.push_back(x ) | 追加x的拷贝到容器的末尾 |
c.pop_back() | 直接移除容器内的最后一个元素,不反复其值 |
c.insert(pos, x ) | 在 pos 所指位置之前插入元素 x 的副本 |
c.insert(pos,n,x ) | 在pos 所指位置之前插入元素x 的 n 个副本 |
c.insert(pos,begin,end) | 在pos 所指位置之前插入范围 [begin,end) 所有元素的副本 |
c.insert(pos, {x1,x2,x3}) | 在pos 所指位置之前插入初始话列表中元素的副本(c++11) |
c.emplace(pos,args…) | 插入一个新元素,元素通过使用args… 作为参数传递给默认构造函数构造(c++1) |
c.emplace_back(args…) | 在容器末尾插入一个新元素,元素通过使用args… 作为参数传递给默认构造函数构造(c++11) |
c.erase(pos) | 移除迭代器pos所指元素,并且返回下一个元素的迭代器 |
c.erase(begin,end) | 移除范围[begin,end) 之间的所有元素 |
c.resize(num) | 改变容器的大小,当增大时新增区域元素采用默认构造函数构造 |
c.resize(num,x) | 改变容器的大小,当增大时新增区域元素为x 的副本 |
c.clear() | 移除所有元素 |
某些元素访问和元素移除操作中,操作本身是不会进行范围检查的。因此我们在写程序的时候对于这些操作一定要事先进行进行判断,确保操作在合法的范围内进行的。
例如:
std::vector<int> vec;
vec.pop_back();
//这个操作会是未定义行为,会导致运行时错误
//正确的做法
if(!vec.end()) {
vec.pop_back();
}
//还有一个需要注意的是在进行pop_back()前对vec进行的修改
//例如本来vec有一个元素但是在pop_back()之前,你执行erase()操作已经将它删除,所以每一次删除元素的操作前都要检查范围
vector并没有提供直接删除某个特定值元素的操作,如果你需要相应操作可以参考:
//删除所有值为val的元素
std::vector<int> vec;
vec.erase(remove(vec.begin(),vec.end(),val),vec.end());
//删除第一个值为val的元素
std::vector<int>::iterator pos;
pos=find(vec.begin(),vec.end(),val);
if(pos!=vec.end()) {
vec.erase(pos);
}
一些操作实例
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
vector<string> vec;
vec.reserve(5);
vec.push_back("hello,");
vec.insert(vec.end(),{"how","are","you","?"});
cout<<"capacity:"<<vec.capacity()<<endl;
copy(vec.cbegin(),vec.cend(),ostream_iterator<string>(cout," "));
cout<<endl;
swap(vec[1],vec[3]);
vec.insert(find(vec.begin(),vec.end(),"?"),"always");
vec.back()="!";
copy(vec.cbegin(),vec.cend(),ostream_iterator<string>(cout," "));
cout<<endl;
cout<<"size:"<<vec.size()<<endl;
cout<<"capacity:"<<vec.capacity()<<endl;
return 0;
}
输出结果
capacity:5
hello, how are you ?
hello, you are how always !
size:6
capacity:10
版权声明:本文为博主原创文章,未经博主允许不得转载。