文章目录
vector翻译为向量,但是这里使用“变长数组”的叫法更容易理解,也即“ 长度根据需要而自动改变的数组”。
为什么要使用 vector
1.vector可以动态分配内存
在考试题中,有时会碰到只用普通数组会超内存的情况,这种情况使用 vector会让问题的解决便捷许多。vector还支持动态扩容,在内存非常紧张的时候这个特性就能派上用场了。
2.vector重写了比较运算符及赋值运算符
vector 重载了六个比较运算符,以字典序实现,这使得我们可以方便的判断两个容器是否相等(复杂度与容器大小成线性关系)。例如可以利用 vector<char>
实现字符串比较(当然,还是用 std::string
会更快更方便)。另外 vector 也重载了赋值运算符,使得数组拷贝更加方便。
3.vector便利的初始化
由于 vector
重载了 = 运算符,所以我们可以方便的初始化。此外从 C++11 起 vector
还支持 列表初始化,例如 vector<int> data {1, 2, 3};
。
4. 以邻接表的方式储存图
vector还可以用来以邻接表的方式储存图,这对无法使用邻接矩阵的题目(结点数太多)又害怕使用指针实现邻接表的读者是非常友好的,写法也非常简洁。
作为 OIer,对程序效率的追求远比对工程级别的稳定性要高得多,而 vector 由于其对内存的动态处理,时间效率在部分情况下低于静态数组,并且在 OJ 服务器不一定开全优化的情况下更加糟糕。所以在正常存储数据的时候,除了以上几个特定情况,通常不选择 vector。
基本函数实现
- 头文件
#include<vector>
- 单独定义一个vector
vector<typename>name;
这相当于是一维数组name[size]
-
定义vector数组
写法一vector<vector<int>> name;
写法二
vector<typename> Arrayname[arraySize];
这相当于二维数组,Arrayname[0]~Arrayname[arraySize-1]中每一个都是一个vector容器。但与 vector<vector> name不同的是,这种写法的一维长度已经固定为 arraysize,另一维才是“变长”的
容器内元素的访问
-
通过下标访问
-
通过迭代器访问
定义
vector<typename>::iterator it;
指向首元素地址
it = vi.begin();
(具体用法结合最后的例子理解)
常用函数
-
增加、修改函数
-
push_back()
push_back(x)就是在后面添加一个元素x -
void assign(int n,const T& x)
设置向量中前n个元素的值为x -
void assign(const_iterator first,const_iterator last)
向量中[first,last)中元素设置成当前向量元素 -
iterator insert(iterator it,const T& x)
向量中迭代器指向元素前增加一个元素x -
iterator insert(iterator it,int n,const T& x)
向量中迭代器指向元素前增加n个相同的元素x -
iterator insert(iterator it,const_iterator first,const_iterator last)
向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据
-
-
删除元素
pop_back()
删除最后面的一个元素clear()
清空向量中所有元素- iterator erase(iterator it):删除向量中迭代器指向元素
- iterator erase(iterator first,iterator last):删除向量中[first,last)中元素
-
size()
获取vector中元素的个数,返回值是unsigned类型 -
遍历函数
- reference at(int pos):返回pos位置元素的引用
- reference front():返回首元素的引用
- reference back():返回尾元素的引用
- iterator begin():返回向量头指针,指向第一个元素
- iterator end():返回向量尾指针,指向向量最后一个元素的下一个位置
- reverse_iterator rbegin():反向迭代器,指向最后一个元素
- reverse_iterator rend():反向迭代器,指向第一个元素之前的位置
-
判断函数
- bool empty() const:判断向量是否为空,若为空,则向量中无元素
示例
基本用法
#include<iostream>
#include<vector>
using namespace std;
int main() {
vector<int> vi;
// 在最后添加元素
for (int i = 0; i < 5; i++)
vi.push_back(i);
// 迭代器
vector<int>::iterator it = vi.begin();
// 如果知道元素个数时
for (int i = 0; i < 5; i++)
{
cout << vi[i]; //通过下标访问
cout << *(it + i)<< " "; //通过迭代器访问
}
// 如果不知道元素个数
// 方法一 size()
cout << endl;
for (int i = 0; i < vi.size(); i++)
cout << vi[i]<< " ";
cout << endl;
// 方法二 利用迭代器
for (it = vi.begin(); it != vi.end(); it++)
cout << *it << " ";
vi.pop_back(); // 删除尾元素5
cout << endl;
for (int i = 0; i < vi.size(); i++)
cout << vi[i] << " ";
// 插入元素
it = vi.begin();
vi.insert(it + 3, -1);
cout << endl;
for (int i = 0; i < vi.size(); i++)
cout << vi[i] << " ";
// 删除元素
// 删除单个元素
vi.erase(vi.begin() + 3);
cout << endl;
for (int i = 0; i < vi.size(); i++)
cout << vi[i] << " ";
// 删除一个区间内元素
vi.erase(vi.begin(),vi.begin()+2);
cout << endl;
for (int i = 0; i < vi.size(); i++)
cout << vi[i] << " ";
}
排序
注意:sort 需要头文件#include<algorithm>
#include <string.h>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
vector<int>obj;
obj.push_back(1);
obj.push_back(3);
obj.push_back(0);
sort(obj.begin(),obj.end());//从小到大排序
cout<<"从小到大:"<<endl;
for(int i=0;i<obj.size();i++)
{
cout<<obj[i]<<",";
}
cout<<"\n"<<endl;
cout<<"从大到小:"<<endl;
reverse(obj.begin(),obj.end());//反向迭代器,从大到小
for(int i=0;i<obj.size();i++)
{
cout<<obj[i]<<",";
}
return 0;
}
输出结果;
从小到大:
0,1,3,
从大到小:
3,1,0,