之前就已经接触过vector,知道这个代表着不定长数组,然后也知道一些常用的用法,碰到别人的题解虽然不熟练但基本都能看得懂,但自己做题目要用到的时候还总是感觉缺了点什么,于是乎从头又认真系统地学了一遍,在这里详细记录下自己的学习心得和总结。
以下所有代码均在DEV5.11环境中编译测试通过。
一、vector是什么
有些时候想开一个数组但却不知道开多大的数组比较好,因为数组的长度可能会有变化,这时候我们就需要运用到动态数组,也就是不定长数组vector。
关于它和动态内存申请的区别,至少vector比较好用吧,说实话。这里留着一个坑,回头系统研究后填上。
二、vector怎么用
①C++中vector头文件就叫vector。
②现在就让我们来定义一个vector动态数组:vector< T > a1;这里定义了一个名称为a1,存储的数据类型为T的动态数组,T可以为常用的int、float、double、long long等标准类型,也可以为自定义类型,例如结构体等。例如我们在这里定义了一个整型动态数组a2:vector< int > a2,值得注意的是,与int a2[90] 不同的是,这里的a2默认为空
③想要在vector动态数组中插入元素要用到自带的push_back操作函数,例如我们要给一个string类型的动态数组s1输入元素,可以如下操作
#include <iostream>
#include <vector>
using namespace std;//STL的调用一般都需要事先声明命名空间,养成好习惯!
int main()
{
vector<string> s1;
s1.push_back("CHINA"); //{"CHINA"}
s1.push_back("England");//{"CHINA","England"}
s1.push_back("France");//{"CHINA","England","France"}
return 0;
}
与此同时我们可以通过size()来获取动态数组的长度,通过类似数组中的[],对vector中的元素进行访问。
#include <iostream>
#include <vector>
using namespace std;//STL的调用一般都需要事先声明命名空间,养成好习惯!
int main()
{
vector<string> s1;
s1.push_back("CHINA"); //{"CHINA"}
s1.push_back("England");//{"CHINA","England"}
s1.push_back("France");//{"CHINA","England","France"}
for(int i = 0; i < s1.size(); i++)
{
cout << s1[i] << endl;
}
}
运行结果:
值得注意的是:push_back操作和后面我会写的栈、队列的STL的机理一样,都是将元素插入到最后的,原因是算法复杂度将会因此从O(n)简化为O(1);
当我们要修改某个元素的时候,直接访问用=修改就好了:s1[1] = “America”,即将上程序中写的England替换为了America。代码和运行结果如下:
#include <iostream>
#include <vector>
using namespace std;//STL的调用一般都需要事先声明命名空间,养成好习惯!
int main()
{
vector<string> s1;
s1.push_back("CHINA"); //{"CHINA"}
s1.push_back("England");//{"CHINA","England"}
s1.push_back("France");//{"CHINA","England","France"}
s1[1] = "America";//{"CHINA","America","France"}
for(int i = 0; i < s1.size(); i++)
{
cout << s1[i] << endl;
}
return 0;
}
删除元素需要用到pop_back(),与插入一样的是对数组最后面的元素进行操作
#include <iostream>
#include <vector>
using namespace std;//STL的调用一般都需要事先声明命名空间,养成好习惯!
int main()
{
vector<string> s1;
s1.push_back("CHINA"); //{"CHINA"}
s1.push_back("England");//{"CHINA","England"}
s1.push_back("France");//{"CHINA","England","France"}
s1[1] = "America";//{"CHINA","America","France"}
s1.pop_back();//{"CHINA","England"}
s1.pop_back();//{"CHINA"}
for(int i = 0; i < s1.size(); i++)
{
cout << s1[i] << endl;
}
return 0;
}
清空vector数组需要用的是clear():
#include <iostream>
#include <vector>
using namespace std;//STL的调用一般都需要事先声明命名空间,养成好习惯!
int main()
{
vector<string> s1;
s1.push_back("CHINA"); //{"CHINA"}
s1.push_back("England");//{"CHINA","England"}
s1.push_back("France");//{"CHINA","England","France"}
s1.clear();//清空数组内容。
for(int i = 0; i < s1.size(); i++)
{
cout << s1[i] << endl;
}
return 0;
}
值得注意的是,clear()操作清空的只是内容,不是回收了申请的空间!
vector < string >().swap(s1);
用这种方式可以清空动态数组申请的内存。
vector基本方法的总结:
方法 | 功能 |
---|---|
push_back(); | 在末尾插入一个元素 |
pop_back(); | 删除当前末尾的元素 |
clear | 清空动态数组的内容(注意是内容) |
size() | 获取当前数组的长度 |
按照前辈的说法,算法竞赛中能用到的基本操作就是这些了。
④二维vector的定义
二维动态数组的每一维的长度都可以不一样,可以是任意形状的。
借助构造函数,我们可以快速构造一个有n行m个元素的动态数组,每个元素的初始值是 0:
vector <vector < int > > vec2(n, vector< int >(m, 0))。
动态数组的初始化必须要注意类比数组,每一行都是一个不定长度的vector,也就意味着我们必须要注意到非法内存访问的存在。
int n = 10;
vector<vector > vec2;
for (int i = 0; i < n; i++) {
vec2[i].push_back(i);
}
上面的这种写法就是很典型的非法访问内存。
vector的维度可以像数组一样更多,但是超过两维以后操作起来会比较麻烦,所以一般用vector都只到两维。
--------分----------------界---------------线-------------
后面会继续更新。