本文将分4点介绍C++ vector库的用法
- vector的初始化
- vector对象的操作
2.1 vector迭代器 - vector整体操作
- 二维vector
- 测试
- vector的一些特性
1. vector的初始化赋值
头文件:#include < vector>
类型:
vector<int/char/string/基本数据类型/自定义类型/结构体类型/…>vec ;
(1)vector<int> a(10); //定义了10个整型元素的向量,初值为0
(2)vector<int> a(10,1); //定义了10个整型元素的向量,且给出每个元素的初值为1
(3)int b[7]={1,2,3,4,5,9,8};
vector<int> a(b,b+7); //从数组中获得初值
(4)vector<int> a(b.begin(),b.begin+3); //其中b是vector
(5)vector<int> a(b); //用b向量来创建a向量,整体复制性赋值
(6)vector<int> a = {1,2,3,4,5,6,7};
2. vector对象的操作
(1)对象的访问
vec.begin(); //第一个元素的指针,注意是指针
vec.end(); //vector中最后一个元素+1的指针
vec[0],vec[1],vec[2].............. //vector对象的访问
vec[0][1].............. //vector二维对象的访问
vec.front(); //vector中得到第一个元素的值
vec.back(); //vector中得到最后一个元素的值
vec.at(i); //相当于vec[i];
2. 1 vector迭代器
除了使用下标来访问vector对象的元素外,标准库还提供了另一种检测元素的方法:使用迭代器(iterator)。迭代器是一种允许程序员检查容器内元素,并实现元素遍历的数据类型。
标准库为每一种标准容器(包括vector)定义了一种迭代器类型。迭代器类型提供了比下标操作更一般化的方法:所有的标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作。因为迭代器对所有的容器都适用,现代C++程序更倾向于使用迭代器而不是下标操作访问容器元素,即使对支持下标操作的vector类型也这样。
(1)定义迭代器类型
vector<int>::iterator iter;
(2)begin和end操作
vector<int>::iterator iter = ivec.begin(); //上述语句把iter初始化为由名为begin的vector操作返回的值。假设vector不空,初始化后,iter即指该元素为ivec[0]。
由end操作返回的迭代器指向vector的“末端元素的下一个”。由end操作返回的迭代器并不指向vector中任何实际的元素,相反,它只是起一个哨兵(sentinel)的作用,表示我们已处理完vector中所有元素。
(3)赋值和自增
*iter = 0; //假设iter指向vector对象ivec的第一个元素,那么*iter和ivec[0]就是指向同一个元素。上面这个语句的效果就是把这个元素的值赋为0。
++iter // 如果iter指向第一个元素,则++iter指向第二个元素。
(4)遍历操作
vector<int> b = {1,2,3,4,5,6,7};
for (vector<int>::iterator ix = b.begin(); ix != b.end(); ++ix){
cout << *ix << endl;
*ix = 0;
}
结果,输出1,2,3,4,5,6,7 全部赋值伟0
(2)获取大小
int count = vec.size();
(3)判断是否为空
vec.empty();
(4)插入
vec.push_back(a); //尾部插入数据
vec.insert(vec.begin()+i,a); //在第 i+1 个元素前面插入a
vec.insert(vec.end()-i,a); //在倒数第i 个元素前面插入a
(5)删除
vec.pop_back(a); // 尾部删除数据
vec.erase(vec.begin()+2); //删除第3个元素
vec.erase(vec.begin()+i,vec.begin()+j); //删除区间[i,j-1]的元素;
vec.erase(vec.begin(),vec.end()-vec.size()+2);//删除前2个元素;
vec.erase(vec.end()-2,vec.end());//删除后2个元素;
vec.clear(); //清空容器
(6)交换vector两个容器的值:
a.swap(vec); //用vec容器替换a容器
3. vector整体操作
(1)排序
需要头文件#include < algorithm>
sort(vec.begin(),vec.end()); //这样默认是升序
升序的另一种写法:
#include <algorithm>
bool cmp(int a,int b){
return a<b;
}
sort(vec.begin(),vec.end(),cmp); // 按升序排序
降序:
#include <algorithm>
bool cmp(int a,int b){
return a>b;
}
sort(vec.begin(),vec.end(),cmp); // 按降序排序
(2)翻转
#include <algorithm>
reverse(vec.begin(),vec.end());
(3)去重
去重需要用到迭代器iterator,而且去重前,要先排好序
去重一般是sort+unique+erase 三个API一起用
sort(vec.begin(),vec.end());
vector<int>::iterator iter = unique(vec.begin(), vec.end());
vec.erase(iter,vec.end());
for (iter = vec.begin(); iter != vec.end(); iter++)
cout << *iter << " ";
也可以直接使用组合:
sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(), vec.end()),vec.end());
for (int i = 0; i < vec.size(); i++)
cout << vec[i] << " ";
(4)查找
(1)在一维数组vec里查找元素3,并删除
vector<int>::iterator iter=find(vec.begin(),vec.end(),3);
if (iter!=vec.end()){
cout << "找到坐标为" <<iter<< endl;
vec.erase(iter);
}
4. 二维vector
上面介绍的都是一维数组的初始化方法,那么二维数组如何初始化
定义二维数组的两种方式
(1)使用vector
//初始化一个m*n的二维数组
vector<vector<int> > array(m);
for(int i=0;i<m;i++)
{
array[i].resize(n);
}
其中vec.resize(n)表示重新调整vec容器的大小为n, 默认为0
也可以:
vector<vector<int>> vec1(row) ; //二维数组的 vector 定义
//初始化一个row x column 的矩阵,数值为 333
for(int i = 0 ;i < row ;++i){
for(int j= 0 ;j < column ;++j){
vec1[i].push_back(3);
}
}
其中row为行,column为列
//创建一个row行,column列(初始值均为0)的二维数组
vector<vector<int>> vec(row,vector<int>(column,0));
其中vec.size() 就是”二维数组”的行数
其中vec[0].size() 就是”二维数组”的列数
(2)C++构建二维动态数组
int **p;
p = new int*[10]; //注意,int*[10]表示一个有10个元素的指针数组
for (int i = 0; i < 10; ++i)
{
p[i] = new int[5];
}
这样,创建出来的就是10*10,并且初始值都为5的二维数组
同理,三维数组的定义为:
vector<vector<vector<int>>> vv;
二维数组增加行和列
vector<vector<int>> vec(row,vector<int>(column,0));
vector<int> temp(0) ;
vec.push_back(temp); //增加行
for(int i = 0 ;i < vec.size();++i ) //vec.size()为行数
vec[i].push_back(555); //增加列
二维数组删除行和列
vector<vector<int>> vec(row,vector<int>(column,0));
for(int i = 0 ;i < vec.size();++i ) //vec.size()为行数
vec[i].pop_back(); //删除列
//删除行
vec.pop_back();
5. 测试
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void printvec(vector<int>&vec){
for(int i = 0;i<vec.size();i++){
cout<<vec[i];
}
cout<<endl;
}
void printvec_2V(vector<vector<int>>&vec){
for(int i = 0;i<vec.size();i++){
for(int j =0;j<vec[0].size();j++)
cout<<vec[i][j];
cout<<endl;
}
}
bool cmp(int a,int b){
return a>b; //对vec进行降序排序
//return a<b; //对vec进行升序排序
}
int main() {
int b[] = {8,1,4,7,3,7,6};
vector<int> vec={6,2,9,3,5,6,8};
vector<int> vec_tmp=vec;
//一、初始化的几种方式
cout<<"一、初始化的几种方式"<<endl;
cout<<" 初始化0:";printvec(vec);
vector<int>vec_1(10);cout<<" 初始化1:";printvec(vec_1);
vector<int>vec_2(10,1);cout<<" 初始化2:";printvec(vec_2);
vector<int>vec_3(vec);cout<<" 初始化3:";printvec(vec_3);
vector<int>vec_4(vec.begin(),vec.begin()+3);cout<<" 初始化4:";printvec(vec_4);
vector<int>vec_5(b,b+sizeof(b)/sizeof(int));cout<<" 初始化5:";printvec(vec_5);
//二、vector对象的操作
//1.对象的访问
cout<<"二、vector对象的操作"<<endl;
cout<<"1.对象的访问作"<<endl;
cout<<" 读取vec[2]:"<<*(vec.begin()+2)<<endl; //vec[2]
cout<<" 读取最后一个元素:"<<*(vec.end()-1)<<endl; //最后一个元素
cout<<" 读取第一个元素:"<<vec.front()<<endl;
cout<<" 读取最后一个元素:"<<vec.back()<<endl;
//2.迭代器
cout<<"2.迭代器"<<endl;
cout<<" 使用迭代器打印容器: ";
for(vector<int>::iterator iter = vec.begin();iter!=vec.end();iter++)
cout<<*iter;
cout<<endl;
//3.获取大小
cout<<"3.获取大小"<<endl;
cout<<" 获取容器的大小: "<<vec.size()<<endl;
//4.判断是否为空
cout<<"4.判断是否为空"<<endl;
cout<<" 判断是否为空: "<<vec.empty()<<" ,0表示不为空,1表示空"<<endl;
//5. 插入
cout<<"5.插入操作"<<endl;
cout<<" 插入前:";printvec(vec);
cout<<" vec.push_back(2)尾部插入2: ";vec.push_back(2);printvec(vec); //尾部插入数据
cout<<" vec.insert(vec.begin()+2,1) 在第 3 个元素前面插入1: ";vec.insert(vec.begin()+2,1);printvec(vec); //在第 i+1 个元素前面插入a
cout<<" vec.insert(vec.end()-2,5) 在倒数第2 个元素前面插入5: ";vec.insert(vec.end()-2,5);printvec(vec); //在倒数第i 个元素前面插入a
//6. 删除
cout<<"6.删除操作"<<endl;
cout<<" vec.pop_back()尾部删除1个数据: ";vec.pop_back();printvec(vec); // 尾部删除数据
cout<<" vec.erase(vec.begin()+2)删除第3个元素: ";vec.erase(vec.begin()+2);printvec(vec); //删除第3个元素
cout<<" vec.erase(vec.begin()+1,vec.begin()+3)删除区间[1,2]的元素: ";vec.erase(vec.begin()+1,vec.begin()+3);printvec(vec); //删除区间[i,j-1]的元素;
cout<<" vec.erase(vec.begin(),vec.end()-vec.size()+2)删除前2个元素: ";vec.erase(vec.begin(),vec.end()-vec.size()+2);printvec(vec);//删除前2个元素;
cout<<" vec.erase(vec.end()-2,vec.end())删除后2个元素: ";vec.erase(vec.end()-2,vec.end());printvec(vec);//删除后2个元素;
cout<<" vec.clear()清空容器: ";vec.clear();printvec(vec); //清空容器
vec = vec_tmp;
cout<<" 恢复原来的值: ";printvec(vec);
cout<<endl;
//7. 交换vector两个容器的值
cout<<" vec_2 = :";printvec(vec_2);
cout<<" vec = :";printvec(vec);
cout<<" 交换后 = :";vec.swap(vec_2);printvec(vec);
vec = vec_tmp;
cout<<" 恢复原来的值: ";printvec(vec);
cout<<endl;
cout<<"三、vector整体操作"<<endl;
cout<<"1.排序,需要#include <algorithm>"<<endl;
cout<<" 对vec进行升序排序: ";sort(vec.begin(),vec.end());printvec(vec); //这样默认是升序
cout<<" 对vec进行降序排序:";sort(vec.begin(),vec.end(),cmp);printvec(vec); //这样默认是升序
/*
升序的另一种写法:
#include <algorithm>
bool cmp(int a,int b){
return a<b;
}
sort(vec.begin(),vec.end(),cmp); // 按升序排序
#include <algorithm>
bool cmp(int a,int b){
return a>b;
}
sort(vec.begin(),vec.end(),cmp); // 按降序排序
*/
cout<<"2.翻转,需要#include <algorithm>"<<endl;
cout<<" 对vec进行翻转序: ";reverse(vec.begin(),vec.end());printvec(vec);
cout<<"3.去重,需要#include <algorithm>,需要先sort排序才可使用"<<endl;
cout<<" 对vec进行去重: ";vector<int>::iterator iter = unique(vec.begin(), vec.end());vec.erase(iter,vec.end());printvec(vec);
cout<<" 对vec进行去重,第二种写法: ";vec.erase(unique(vec.begin(), vec.end()),vec.end());printvec(vec);
cout<<"4.查找"<<endl;
vector<int>::iterator iter_1=find(vec.begin(),vec.end(),3);
if (iter_1!=vec.end()){
cout << " 查找到指定值:" <<*iter_1<< endl;
vec.erase(iter_1);
cout << " 删除后: " ;printvec(vec);
}
cout<<"四、二维vector"<<endl;
cout<<"1.定义5*6的二维vec_double,初始值为1"<<endl;
vector<vector<int>> vec_double(5,vector<int>(6,1));
printvec_2V(vec_double);
cout<<"二维数组的行数为"<<vec_double.size()<<endl;
cout<<"二维数组的列数为"<<vec_double[0].size()<<endl;
cout<<"2.定义3*4的二维vec1,初始值为3"<<endl;
vector<vector<int>> vec1(3) ; //二维数组的 vector 定义
//初始化一个row x column 的矩阵,数值为 333
for(int i = 0 ;i < 3 ;++i){
for(int j= 0 ;j < 4 ;++j){
vec1[i].push_back(3);
}
}
printvec_2V(vec1);
cout<<"二维数组的行数为"<<vec1.size()<<endl;
cout<<"二维数组的列数为"<<vec1[0].size()<<endl;
cout<<"3.删除vec1的最后一列"<<endl;
for(int i = 0 ;i < vec1.size();++i ) //vec.size()为行数
vec1[i].pop_back(); //删除列
printvec_2V(vec1);
cout<<"4.删除vec1的最后一行"<<endl;
vec1.pop_back(); //删除行
printvec_2V(vec1);
cout<<"5.增加一行{1,2,3}"<<endl;
vec1.push_back({1,2,3}); // 也可以是vec1.push_back(vec);其中vec = {1,2,3}
printvec_2V(vec1);
cout<<"5.增加全为1的一列"<<endl;
for(int i = 0 ;i < vec1.size();++i ) //vec.size()为行数
vec1[i].push_back(1); //删除列
printvec_2V(vec1);
return 0;
}
结果打印:
一、初始化的几种方式
初始化0:6293568
初始化1:0000000000
初始化2:1111111111
初始化3:6293568
初始化4:629
初始化5:8147376
二、vector对象的操作
1.对象的访问作
读取vec[2]:9
读取最后一个元素:8
读取第一个元素:6
读取最后一个元素:8
2.迭代器
使用迭代器打印容器: 6293568
3.获取大小
获取容器的大小: 7
4.判断是否为空
判断是否为空: 0 ,0表示不为空,1表示空
5.插入操作
插入前:6293568
vec.push_back(2)尾部插入2: 62935682
vec.insert(vec.begin()+2,1) 在第 3 个元素前面插入1: 621935682
vec.insert(vec.end()-2,5) 在倒数第2 个元素前面插入5: 6219356582
6.删除操作
vec.pop_back()尾部删除1个数据: 621935658
vec.erase(vec.begin()+2)删除第3个元素: 62935658
vec.erase(vec.begin()+1,vec.begin()+3)删除区间[1,2]的元素: 635658
vec.erase(vec.begin(),vec.end()-vec.size()+2)删除前2个元素: 5658
vec.erase(vec.end()-2,vec.end())删除后2个元素: 56
vec.clear()清空容器:
恢复原来的值: 6293568
vec_2 = :1111111111
vec = :6293568
交换后 = :1111111111
恢复原来的值: 6293568
三、vector整体操作
1.排序,需要#include <algorithm>
对vec进行升序排序: 2356689
对vec进行降序排序:9866532
2.翻转,需要#include <algorithm>
对vec进行翻转序: 2356689
3.去重,需要#include <algorithm>,需要先sort排序才可使用
对vec进行去重: 235689
对vec进行去重,第二种写法: 235689
4.查找
查找到指定值:3
删除后: 25689
四、二维vector
1.定义5*6的二维vec_double,初始值为1
111111
111111
111111
111111
111111
二维数组的行数为5
二维数组的列数为6
2.定义3*4的二维vec1,初始值为3
3333
3333
3333
二维数组的行数为3
二维数组的列数为4
3.删除vec1的最后一列
333
333
333
4.删除vec1的最后一行
333
333
5.增加一行{1,2,3}
333
333
123
5.增加全为1的一列
3331
3331
1231
6. vector的一些特性
- vector的内存占用空间只增不减,不论使用erase还是clear,vector用的内存空间不变,所有内存空间是在vector析构时候才能被系统回收
- size()成员指当前拥有的元素个数;capacity()成员指当前(容器必须分配新存储空间之前)可以存储的元素个数。reserve()成员可以用来控制容器的预留空间。
- 每当vector容器不得不分配新的存储空间时,会以加倍当前容量的分配策略实现重新分配。例如,
当前capacity为50,当添加第51个元素时,预留空间不够用了,vector容器会重新分配大小为100的内存空间,作为新连续存储的位置。
- vec.reserve()是控制容器的预留空间,而vec.reverse()是翻转
- swap()是交换函数,使vector离开其自身的作用域,从而强制释放vector所占的内存空间,总而言之,释放vector内存最简单的方法是vector.swap(nums)。