C++的vector的使用
本文为学习C++的阅读、学习笔记,如有错漏请联系作者。1. 基本概念vector是一个类模板,在C++中使用模板可以编写一个类定义或函数定义,而用于多种不同的数据类型。vector是同一种类型的对象的集合,由于可以包含其他对象的特性,所以也将vector称为容器。2. 使用方法要使用vector类模板,需要添加头文件,并使用using声明:#include <vector>using
本文为学习C++的阅读、学习笔记,如有错漏请联系作者。
1. 基本概念
vector是一个类模板,在C++中使用模板可以编写一个类定义或函数定义,而用于多种不同的数据类型。vector是同一种类型的对象的集合,由于可以包含其他对象的特性,所以也将vector称为容器。
2. 使用方法
要使用vector类模板,需要添加头文件,并使用using声明:
#include <vector>
using std::vector;
关于使用using声明,避免在头文件中进行using声明,以免存在多个文件中都进行了using声明导致重定义等错误。
2.1 定义和初始化
将类型放在类模板(vector)后的尖括号来指定类型,如下面这个声明表示ivec是保存的是一个int类型的对象:
vector<int> ivec;
vector对象的初始化方法:
其中,尖括号的T表示类模板vector所支持的数据类型。在C语言初始化的时候,一般会预先分配合适的空间,但是在C++中,通常是先初始化一个空vector对象,然后再动态地增加元素。
初始化时,如果没有指定元素的初始化式,则标准库将会自行提供一个元素初始值进行初始化。
使用vector<T> v5{1,2,3,4}这种初始化方法,将一个序列放入vector中。
2.2 vector对象的操作
增删查改是最基本的数据操作,书中提到了以下几种vector操作的函数:
其中,push_back(t)是在vector对象末尾添加一个元素t;size()是获得vector对象的个数。
访问一个vector对象可以使用for循环和迭代器进行遍历,也可以使用下标的形式进行访问:
vector<int> num1{1,2,1,2};
//使用迭代器访问
for (vector<int>::iterator iter = num1.begin(); iter != num1.end(); iter++) {
cout << *iter << endl;
}
//下标访问
for (int i = 0; i < num1.size(); i++) {
cout << num1[i] << endl;
}
C++还提供了一种叫做范围for循环的for语句,可以用作遍历vector对象:
vector<int> test{1,2,3,4,5,6};
for (auto &i : test) {
cout << i << " ";
}
以上是遍历vector对象的方式,查找了其他的资料,找到了删除操作的几个函数,参考博文:vector删除元素之pop_back(),erase(),remove()。使用pop_back()可以删除vector对象的最后一个元素,而采用remove()一般情况下不会改变容器的大小,而pop_back()与erase()等成员函数会改变容器的大小。
2.3 示例
示例说明:初始化vector对象,紧接着使用范围for循环对vector对象进行遍历;使用push_back函数和pop_back函数进行增加对象和删除对象,vector对象也可以使用下标进行访问或操作。如果不了解范围for循环的,可以参考博文:C++11新特性之基本范围的For循环(range-based-for)。
#include <iostream>
#include <vector>
int main() {
//initial the test_vector: there are 15 integer, and initial value is 10.
std::vector<int> test_vector(15, 10);
std::cout << "its size is :"<< test_vector.size() << std::endl;
//traverse the test_vector
for (std::vector<int>::iterator itr = test_vector.begin(); itr != test_vector.end(); itr++) {
std::cout << *itr << " ";
}
//add
test_vector.push_back(20);
std::cout << "\nits size is :" << test_vector.size() << std::endl;
//use subscript to operation
std::cout << "the last value is :" << test_vector[test_vector.size()-1] << std::endl;
//delete
test_vector.pop_back();
std::cout << "its size is :" << test_vector.size() << std::endl;
std::cout << "the last value is :" << test_vector[test_vector.size() - 1] << std::endl;
return 0;
}
示例效果:
its size is :15
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10its size is :16
the last value is :20
its size is :15
the last value is :10
2.5 vector嵌套vector对象
上面是简单使用vector的方法,后来用到了一些稍微复杂一点的用法,就是vector的嵌套,这里补充添加上来。(2020/08/26)
vector是一个模板,能够容纳接大多数类型的对象作为其元素,甚至组成vector的元素也可以是vector。早期版本的C++标准中,如果声明vector的元素为vector类型时,应该在vector对象的末尾添加一个空格,写成:vector<vector<int> >;而在C++11新标准则不需要添加这个空格。
这里以vector<vector<int>>这个声明为例,我们可以把它与二维数组进行类比,下面通过下标访问的方式访问vector对象:
vector<int> test;
vector<vector<int>> test2{ { 1,2,3,4,5,6,7 },{ 1,2,3,4,5,6 }};
for (int i = 0; i <test2.size(); i++) {
test = test2[i];
for (int j = 0; j < test.size(); j++) {
cout << test2[i][j] << " ";
}
cout << "\n";
}
输出结果:
1 2 3 4 5 6 7
1 2 3 4 5 6
这样我们就可以使用类似二维数组的方式对vector嵌套vector对象的变量进行操作了。
2.6 vector的拷贝
假设声明了test变量,要实现对test变量的拷贝:
vector<int> test{1,2,3,4};
有下面几种方法:
(1)声明新变量时,初始化拷贝
这种声明方法不会改变原来变量中的数据:
vector<int> tmp(test);
(2)利用vector的assign函数
复制了一份数据,test中的数据也是不变:
vector<int> tmp;
tmp.assign(test.begin(), test.end());
(3)利用vector的swap函数
将test中数据全部移到temlist中,此时test中为空了
vector<int> tmp;
tmp.swap(test);
(4)利用vector的insert函数
这种拷贝方式是在原有的数据的尾部插入目标数据,相当于复制了一份数据:
tmp.insert(tmp.end(), test.begin(), test.end());
2.7 存储自定义数据类型
自定义结构体, 重载 ==操作符:
typedef struct _Point
{
int x;
int y;
_Point(int _x, int _y)
{
x = _x;
y = _y;
}
bool operate ==(const int _x, const int _y)const
{
return ((x == _x)&&(y == _y));
}
}Point;
添加和访问都通过迭代器:
std::vector<Point> test;
auto it = find(test.begin(), test.end(), tmp);
if(it != test.end())
{
(*it).x = 10;
(*it).y = 10;
}
更多推荐
所有评论(0)