- 1. 简介
- 2. 使用注意
- 3. 基本操作
- 3.1 头文件
- 3.2 创建vector对象
- 3.3 尾部插入元素 `push_back()`
- 3.4 尾部删除元素 `pop_back()`
- 3.5 使用下标访问元素`[]`
- 3.6 使用`at()`方法访问
- 3.7 使用迭代器访问元素
- 3.8 插入元素 `insert()`
- 3.9 删除元素 `erase()`
- 3.10 vectors实际存储元素个数 `size()`
- 3.11 vectors容量大小 `capacity()`
- 3.12 清空 `clear()`
- 3.13 使用 `reverse()` 将元素翻转
- 3.14 `swap()` 交换 vector
- 3.15 `sort()` 排序
- 3.16 改变vector的大小 `resize()`
- 3.17 改变vector容量的大小 `reserve()`
- 4.一维数组的使用
- 5.二维数组的使用
- 6. `begin()`与`end()` 、`front()`与`back()`区别
- 7. `resize()` 和 `reserve()`
- 8. Reference
1. 简介
在c++中,vector是一个十分有用的容器。
作用:它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。vector在C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。
2. 使用注意
1、如果你要表示的向量长度较长(需要为向量内部保存很多数),容易导致内存泄漏,而且效率会很低;
2、Vector作为函数的参数或者返回值时,需要注意它的写法:
double Distance(vector<int>&a, vector<int>&b) // 其中的 “&” 绝对不能少!!!
3. 基本操作
3.1 头文件
#include <vector>
3.2 创建vector对象
vector<int> v1; // vec是一个空int类型的vector对象,执行默认初始化
vector<int> v2(v1); // v2包含有v1所有元素的副本
vector<int> v2 = v1; // 等价于上面这条语句
vector<int> v3(n, val); // v3包含了n个int类型值为val的元素
vector<int> v4(n); // v4包含了n个重复地执行了值初始化的对象
vector<int> v5 {1, 2, 3}// v5是一个含有3个int类型的vector,其中每个元素被赋予相应的初始值
vector<int> v5 = {1, 2, 3}// 与上面语句等价
3.3 尾部插入元素 push_back()
vec.push_back(1);
3.4 尾部删除元素 pop_back()
vec.pop_back();
3.5 使用下标访问元素[]
cout << vec[0] << endl; // 记住下标是从0开始的。
3.6 使用at()
方法访问
cout << vec.at(0) << endl; // 使用at方法访问,如果vector为空,会抛出异常,下标法则不会(效率更高)
3.7 使用迭代器访问元素
vector<int>::iterator it;
for(it=vec.begin(); it!=vec.end(); it++)
cout << *it << endl;
3.8 插入元素 insert()
vec.insert(vec.begin()+i, a); // 在第i+1个元素前面插入a;
3.9 删除元素 erase()
vec.erase(vec.begin()+2); // 删除第3个元素
vec.erase(vec.begin()+i, vec.end()+j); // 删除区间[i,j-1];区间从0开始
注意:
size()
表示vector实际存储元素个数,capacity()
表示vector容量大小,即分配的存储空间的大小。举例记忆:一间房间有100个座位(capacity),当前只坐了40人(size)。
3.10 vectors实际存储元素个数 size()
vec.size();
3.11 vectors容量大小 capacity()
vec.capacity();
3.12 清空 clear()
vec.clear();
3.13 使用 reverse()
将元素翻转
#include <algorithm>
reverse(vec.begin(), vec.end()); // 将元素翻转,即逆序排列
// (在vector中,如果一个函数中需要两个迭代器,一般后一个都不包含) ? 没看懂
3.14 swap()
交换 vector
vector<int> a(3, 100); // three ints with a value of 100
vector<int> b(5, 100); // five ints with a value of 200
a.swap(b); // swap two vectors
3.15 sort()
排序
#include <algorithm>
sort(vec.begin(),vec.end()); // 默认是按升序排列,即从小到大
// 可以通过重写排序比较函数按照降序比较,如下定义排序比较函数:
bool Comp(const int &a,const int &b) {
return a>b;
}
// 调用时:sort(vec.begin(),vec.end(),Comp); 这样就降序排序。
注意:vector提供了两个方法
resize()
和reserve()
分别对size()
和capacity()
进行操作.
Reference:C++基础篇 – vector的resize函数和reserve函数
3.16 改变vector的大小 resize()
vector<int> vec;
vec.resize(5); // 将空vector数组大小更改为5
vec.resize(8, 35); // 将vec数组大小更改为8,并将新增加的元素,初始化为指定值35
for (int i=0;i<vec.size();i++)
std::cout << ' ' << vec[i];
// 结果为:0 0 0 0 0 35 35 35
1、resize方法被用来改变vector的大小,即vector中元素的数量,我们可以说,resize方法改变了容器的大小,且创建了容器中的对象;
2、如果resize中所指定的n小于vector中当前的元素数量,则会删除vector中多于n的元素,使vector得大小变为n;
3、如果所指定的n大于vector中当前的元素数量,则会在vector当前的尾部插入适量的元素,使得vector的大小变为n,在这里,如果为resize方法指定了第二个参数,则会把后插入的元素值初始化为该指定值,如果没有为resize指定第二个参数,则会把新插入的元素初始化为默认的初始值;
4、如果resize所指定的n不仅大于vector中当前的元素数量,还大于vector当前的capacity容量值时,则会自动为vector重新分配存储空间;
3.17 改变vector容量的大小 reserve()
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vect;
vect.reserve(5);
vect.push_back(1);
vect.push_back(2);
vect.push_back(3);
vect.push_back(4);
cout << vect.size() << endl;
cout << vect.capacity() << endl;
vect.push_back(5);
vect.push_back(6); // 插入两个元素,此时vect的大小大于之前分配的容量5
cout << "size1 = " << vect.size() << endl;
cout << "capacity1 = " << vect.capacity() << endl;
vect.push_back(7);
vect.push_back(8); // 在插入两个元素,和上面的结果进行对比,会有意外收获
cout << "size1_1 = " << vect.size() << endl;
cout << "capacity1_1 = " << vect.capacity() << endl;
vect.reserve(3); // 当程序执行到此处时,vect的容量大小一定是大于3的
cout << "size2 = " << vect.size() << endl;
cout << "capacity2 = " << vect.capacity() << endl;
vect.reserve(12);
cout << "size3 = " << vect.size() << endl;
cout << "capacity3 = " << vect.capacity() << endl;
return 0;
}
/**输出结果
4
5
size1 = 6
capacity1 = 10
size1_1 = 8
capacity1_1 = 10
size2 = 8
capacity2 = 10
size3 = 8
capacity3 = 12
*/
1、reserve方法被用来重新分配vector的容量大小;
2、只有当所申请的容量大小n大于vector的当前容量时,才会重新为vector分配存储空间;
3、reserve方法对于vector的大小(即size)没有任何影响;
4.一维数组的使用
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
int main() {
vector<int> a; // 创建一个int类型的vector数组 a
a.push_back(1);
a.push_back(2); // 把1和2压入vector
cout << a[0] << endl; // 下标法访问数组,输出为1
cout << a.at(1) << endl; // at法访问数组,输出为2
// at和下标法的区别是,如果vector为空,调at会抛出异常,而operator[]索引的行为为定义
// 使用迭代器访问数组元素
for(vector<int>::iterator it = a.begin(); it != a.end(); it++)
cout << *it << endl;
}
5.二维数组的使用
这里简单叙述一下C++ 构建二维动态数组
int **p;
p = new int*[10]; // 注意,int*[10]表示一个有10个元素的指针数组
for (int i = 0; i < 10; ++i)
p[i] = new int[5];
1. 初始化
(1)直接使用初始化方式
vector<vector<int> > a(5, vector<int>(3, 0));
// 得到一个5行,3列,值全为0的二维数组
(2)先定义好二维数组结构,再直接赋值
// 得到一个5行3列的数组
// 由vector实现的二维数组,可以通过resize()的形式改变行、列值
int i, j;
vector<vector<int> > array(5);
for (i = 0; i < array.size(); i++)
array[i].resize(3);
for(i = 0; i < array.size(); i++)
for (j = 0; j < array[0].size();j++)
array[i][j] = (i+1)*(j+1);
(3)利用Vector的push_back函数
vector<vector<int> > vec;
vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
vector<int> b;
b.push_back(4);
b.push_back(5);
b.push_back(6);
vec.push_back(a);
vec.push_back(b);
2. 遍历
(1)利用迭代器
void reverse_with_iterator(vector<vector<int>> vec) {
if (vec.empty()) {
cout << "The vector is empty!" << endl;
return;
}
vector<int>::iterator it;
vector<vector<int>>::iterator iter;
vector<int> vec_tmp;
cout << "Use iterator : " << endl;
for(iter = vec.begin(); iter != vec.end(); iter++) {
vec_tmp = *iter;
for(it = vec_tmp.begin(); it != vec_tmp.end(); it++)
cout << *it << " ";
cout << endl;
}
}
(2)得到行、列大小,利用下标进行遍历
void reverse_with_index(vector<vector<int>> vec) {
if (vec.empty()) {
cout << "The vector is empty!" << endl;
return;
}
int i,j;
cout << "Use index : " << endl;
for (i = 0; i < vec.size(); i++) { // 注意,当内层每个vector没有存满时,这个样会出错
for(j = 0; j < vec[0].size(); j++)
cout << vec[i][j] << " ";
cout << endl;
}
}
注意: vector的元素不仅仅可以是int,double,string,还可以是结构体,但是要注意:结构体要定义为全局的,否则会出错。
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
typedef struct rect {
int id;
int length;
int width;
// 对于向量元素是结构体的,可在结构体内部定义比较函数,下面按照id,length,width升序排序。
bool operator< (const rect &a) const {
if(id!=a.id)
return id<a.id;
else {
if(length!=a.length)
return length<a.length;
else
return width<a.width;
}
}
}Rect;
int main() {
vector<Rect> vec;
Rect rect;
rect.id=1;
rect.length=2;
rect.width=3;
vec.push_back(rect);
vector<Rect>::iterator it=vec.begin();
cout<<(*it).id<<' '<<(*it).length<<' '<<(*it).width<<endl;
return 0;
}
6. begin()
与end()
、front()
与back()
区别
函数原型:
iterator begin();
const_iterator begin();
功能:返回一个当前vector容器中起始元素的迭代器。
函数原型:
iterator end();
const_iterator end();
功能:返回一个当前vector容器中末尾元素的迭代器。
函数原型:
reference front();
const_reference front();
功能: 返回当前vector容器中起始元素的引用。
函数原型:
reference back();
const_reference back();
功能: 返回当前vector容器中末尾元素的引用。
例题
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<char> v1;
vector<char>::iterator iter1;
vector<char>::iterator iter2;
v1.push_back('m');
v1.push_back('n');
v1.push_back('o');
v1.push_back('p');
cout << "v1.front() = " << v1.front() << endl;
cout << "v1.back() = " << v1.back() << endl;
iter1 = v1.begin();
cout << *iter1 << endl;
iter2 = v1.end()-1; // 注意v1.end()指向的是最后一个元素的下一个位置,所以访问最后一个元素
// 的正确操作为:v1.end() - 1;
cout << *iter2 << endl;
return 0;
}
/*
最后输出结果:
v1.front() = m
v1.back() = p
m
p
*/