vector并不是传统意义上向量的意思,在这里更多可以理解为动态数组。
vector初始化
首先,要想使用vector,我们应该引入头文件:
#include <vector>
接下来,我们构建一个动态数组:
vector<int> vec1;
vector不是一个类型,它只是一个类的模板。而vectoe<type>才是类型。也因此,vector<int>和vector<double>不是同一个类型。
除了可以使用已经存在的类型构建动态数组外,也可以使用我们自己定义的结构体类型去定义动态数组。
struct student{
int sno;
string name;
int age;
}
//...
//定义一个动态数组
vector<student> vec2;
除此之外,我们也可以将vector<type>当作类型传递进入vector中去(二维数组),如下:
vector<vector<int>> vec3;
但相较于这种二维数组,在机试中更多使用下列这种方式定义二维数组(动态数组的静态数组):
vector<int> arr[10];
通过上述方式建立的动态数组初始值为空。我们也可以通过以下的方式让动态数组中初始值不为空:
vector<int> vec4(100);//初始数组中就有100个元素
还有这种:
vector<int> vec5={1,2,3,4,5};
vector的尾部插入操作
使用push_back()函数插入新元素,在尾部插入。
vector<int> vec1;
int a=90;
vec1.push_back(a);//将a插入数组的末尾
在尾部插入的效率比较高。
vector的元素访问
我们可以通过数组下标直接访问数组中的某一个元素,与静态数组一致,越界访问也会报错。例如:
vector<int> vec={1,2,3,4,5};
printf("%d",vec[2]);//将会输出3
vector的长度
可以通过size()函数直接查询动态数组的长度。
//vec数组内元素为{1,2,3,4,5}
vec.size();//结果为5
vector数组遍历
第一种方式和静态数组一样,可以使用while或for循环直接循环访问数组内元素。
这里着重介绍第二种方式:
迭代器(iterator)
它提供一种通用的方法。我们可以将迭代器理解为一个高级的指针。它可以像指针一样间接访问我们的元素。
如何定义一个迭代器?
//格式:
动态数组类型(比如vector<int>)::iterator
浅浅理解一下迭代器的工作原理:
动态数组有两个函数:
begin():最开始时指向动态数组中第一个元素的位置。
end():指向动态数组最后一个元素的后一个位置。
迭代器在迭代过程中实际上就是在做自增操作,从第一个元素依次指向后面的元素,直到所有的元素都遍历完(即begin()与end()所指位置相同)。
vector<int> vec={1,2,3,4,5};
vector<int>::iterator it;
for(it=vec.begin();it!=vec.end();it++){
printf("it=%d\n",*it);
}
vector的中间插入操作
迭代器的功能远不止于此。我们还可以利用迭代器往数组中间插入元素。
vector<int> vec={1,2,3,4,5};
vector<int>::iterator it;
it=vec.begin();//it=it+3
vec.insert(it,12);//执行完之后数组变为{12,1,2,3,4,5}
//且在执行完插入操作后,it失效,不再指向vec中第一个元素,
//如果想要继续使用这个迭代器对象,就需要重新为其赋值
vector的删除操作
clear():清空所有数据
vec.clear();
pop_back():删除最后一个元素
vec.pop_back();
erase():删除中间任意一个位置的元素(使用迭代器):
vector<int> vec={1,2,3,4,5,6};
vector<int>::iterator it;
it=vec.begin()+2;//it现在指向vec[2]
不推荐中间插入和删除操作,因为效率很低。