vector是C++ STL库中最常用的容器类,实际上它是一种模板(template)。它支持动态扩容,十分方便,不像数组需要新建空间来扩容。
vector支持大部分类型的对象作为其元素,甚至组成vector的元素可以是vector,也就是说二维数组。比如vector<vector<int>>。
初始化vector的几种方式:
#include<iostream>
#include<vector>
using std::vector;
using std::endl;
using std::cout;
int main(int argc, const char * argv[]){vector<int> v1; // 默认初始化vector<int> v2(3, 1); // 创建包含3个1的数组vector<int> v4 = v1; // 将v1复制给v4return 0;
}
其中最常用的还是 vector<T> v1; 这样就可以在后续的操作中一一添加元素。
比如我需要添加1-100的数进去。
for(int i = 0; i < 100; i++)v1.push_back(i);
不能用下标的形式添加vector元素
比如如下,这是因为v1初始化的时候还是空的。这个错误编译器不会报警,但是运行时会发生缓冲区溢出,我试运行了一下,程序一直卡住不动了。
vector<int> v1for(int i = 0; i < 100; i++)v1[i] = i;
vector遍历方式
1. for遍历
我的i定义的类型为size_t,这是因为vector的size返回的类型为size_t。并且size_t的大小可以保证在所有平台都足够存储。
在输出环节中,我还使用了两种方式,一种是[]定位,一种是调用函数at定位,在C++中[]是重载了at的运算符,使用at函数速度会快一点点,在极端的性能要求条件下,使用at是不错的选择。
for(size_t i = 0; i < v1.size(); i++){std::cout << v1[i] << endl; // 或者// std::cout << v1.at(i) << endl;
}
2.迭代器遍历
for(auto it = v1.begin(); it != v1.end(); it++){cout << *it << endl;}
3. 简单粗暴的基于范围的遍历
这种方式最简单
for (auto i: v1){cout << i << endl;}
vector移除元素
移除最后一个元素
if(!v1.empty()){v1.pop_back();
}
移除中间的元素,比如移除第2个元素,需要注意的是不要越界处理。
v1.erase(v1.begin()+1);
vector性能优化
vector底层扩容的机制是当元素超过某个阈值,新建一个1.5倍的空间(编译器决定,msvc是2倍,gcc是1.5倍),然后把vector整体的旧元素复制到新空间。
vector<int> v3(100); // 初始化的时候指定空间大小v3.resize(100); // 或者自己来重定义空间大小
这两种方式都是自己大概知道会存多少数据进去,在性能优化的时候可以考虑这两种方案,减少vector动态扩容的性能损耗。