vector
简介
头文件#include< vector >
size可动态改变;
会分配额外的空间,以适应size的动态增长;
与其他容器(deques、lists、forward_lists)相比,vector在获取第一个和最后一个元素的操作效率更高,但对于中间元素的操作效率较低。
使用
创建
自动初始化各元素为0
vector<int> vec1(4); //[0,0,0,0]
vector<int>vec2(4, 1); //[1,1,1,1]
vector<int>vec3 = { 1,2,3,4 }; //[1,2,3,4]
复制
vector<int> vec = { 1,2,3,4,5 };
vector<int> vec1(vec); //[1,2,3,4,5]
vector<int> vec2(vec1.begin() + 1, vec1.end() - 1); //[2,3,4]
基于范围的for语句
vector<int>vec = { 1,2,3,4,5 };
for (auto i : vec)
cout << i;
for (auto& i : vec)
cin >> i;
Iterators
Name | Description |
---|---|
begin | 返回指向迭代器第一个元素的指针 |
end | 返回指向迭代器最后一个元素的指针 |
rbegin | 返回迭代器逆序第一个元素的指针 |
rend | 返回迭代器逆序最后一个元素的指针 |
cbegin | 返回常量迭代器的第一个元素的指针 |
cend | 返回常量迭代器的最第一个元素的指针 |
crbegin | 返回常量迭代器逆序的第一个元素的指针 |
crend | 返回常量迭代器逆序的最后一个元素的指针 |
vector<int> vec0 = { 0,1,2,3,4,5,6,7,8,9 };
vector<int>::iterator it1;
for (it1 = vec0.begin(); it1 != vec0.end(); ++it1)
cout << ' ' << *it1 << endl; //[0,1,2,3,4,5,6,7,8,9]
vector<int>::reverse_iterator it2;
for (it2 = vec0.rbegin(); it2 != vec0.rend(); ++it2)
cout << ' ' << *it2 << endl; //[9,8,7,6,5,4,3,2,1,0]
for (auto it3 = vec0.cbegin(); it3 != vec0.end(); ++it3)
cout << ' ' << *it3 << endl; //[0,1,2,3,4,5,6,7,8,9]
for (auto it4 = vec0.crbegin(); it4 != vec0.crend(); ++it4)
cout << ' ' << *it4 << endl; //[9,8,7,6,5,4,3,2,1,0]
其中it3和it4在for中使用auto来定义,使用更加方便。
如果是vec0.begin()+1,则表示从第二个元素开始。
Capacity
Name | Description |
---|---|
size | 返回当前vector使用数据量的大小 |
max_size | 返回vector最大可用的数据量 |
resize | 调整vector中的元素个数 |
capacity | 返回vector中总共可以容纳的元素个数 |
empty | 测试vector是否是空的 |
reserve | 控制vector的预留空间 |
shrink_to_fit | 减少capacity到size的大小 |
max_size与实际硬件有关;
size≤capacity;
resize为n | 变化 |
---|---|
n<size | 销毁尾部 |
size<n≤capacity | 新增元素赋值为0,capacity不变 |
n>capacity | 新增元素赋值为0,size和capacity变为n |
empty:当vector为空时,返回1,不为空返回0;
shrink_to_fit:去掉预留的空间,capacity与size保持一致
vec.reserve(100); //指定vec的容量为100
Element access
Name | Description |
---|---|
operator[] | 在[]中可以做运算 |
at | vector.at(i)相当于vector[i] |
front | 返回第一个元素的值 |
back | 返回最后一个元素的值 |
data | 返回指向vector内存数据的指针 |
vector<int>vec1(5); // [0,0,0,0,0]
int* p = vec1.data(); // vec1 must not be empty
for (int i = 0; i < vec1.size(); ++i) {
*p = i;
++p;
}
for (int i = 0; i < vec1.size(); ++i)
cout << vec1[i] << endl; // [0,1,2,3,4]
Modifiers
Name | Description |
---|---|
assign | 指定vector内容 |
push_back | 在容器的最后一个位置插入元素x |
pop_back | 删除最后一个元素 |
insert | 插入元素 |
erase | 擦除元素 |
swap | 交换两个容器的内容 |
clear | 将容器里的内容清空,size值为0,但是存储空间没有改变 |
emplace | 插入元素(与insert有区别) |
emplace_back | 在容器的最后一个位置插入元素x(与push_back有区别) |
1.assign
assign 主要有三种用法
vector<int> vec1;
vector<int> vec2;
vector<int> vec3;
vec1.assign(5, 10); //[10,10,10,10,10]
vector<int>::iterator it;
it = vec1.begin() + 1;
vec2.assign(it, vec1.end() - 1); //[10,10,10]
int arr[] = { 10,20,30,40 };
vec3.assign(arr, arr + 4); //[10,20,30,40]
2.插入
push_back向容器尾部添加元素时,会先创建这个元素再拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。
insert和emplace(C++11中引入)都可以向vector中间插入元素,但insert可以插入多个元素,emplace一次只能插入一个元素。emplace在插入元素时,在指定位置直接构造元素,而insert是生成元素,再将其赋值或移动到容器中。若是插入一个元素,则emplace性能最佳。
insert有三种用法:
1.在指定位置loc前插入值为val的元素,返回指向这个元素的迭代器;
2.在指定位置loc前插入num个值为val的元素;
3.在指定位置loc前插入区间[start, end)的所有元素。
// method1
vector<int> vec1;
int arr[] = { 1,2,3,4,5 };
vec1.insert(vec1.begin(), arr, arr + 5); //[1,2,3,4,5]
// method2
vector<int> vec2(vec1);
vector<int>::iterator it = vec1.begin() + 2;
vec1.insert(it, 3, 20); // [1,2,20,20,20,3,4,5]
// method3
vector<int> vec3(3, 40);
vector<int>::iterator it2 = vec2.begin();
vec2.insert(it2, vec3.begin(), vec3.end()); // [40,40,40,1,2,3,4,5]
vector<int>vec = { 1,2,3 };
vec.insert(vec.begin(), 5); //[5,1,2,3]
emplace的使用方式为:
iterator emplace(const_iterator pos, args...);
vector<int> vec0{ 1,2,3 };
vec0.emplace(vec0.begin() + 2, 10); //[1,2,10,3]
3.删除
vector中有三种可以删除元素的操作,第一种就是我们上面讲到的pop_back,删除最后一个元素,无返回值;第二种是clear,将容器清空,size变为0,无返回值;第三种是erase,通过迭代器来删除元素,可以删除一个元素,也可以删除某个范围内的元素,返回下一个位置的迭代器。
vector<int> vec0{ 1,2,3,4,5,6,7,8,9,10};
//for (int i = 0; i < 4; ++i) {
// vec0.pop_back();
//}
vec0.erase(vec0.begin() + 3); // [1,2,3,5,6,7,8,9,10]
vec0.erase(vec0.begin(), vec0.begin() + 5); // [7,8,9,10]
//vec0.clear();
4.swap
vector<int> vec1{ 1,2,3,4,5 };
vector<int> vec2{ 10,20,30 };
vec1.swap(vec2);
Allocator
Name | Description |
---|---|
get_allocator | 返回vector的内存分配器 |
vector<int> myvector;
int* p;
int i;
// 使用Allocator为数组分配5个元素的空间
p = myvector.get_allocator().allocate(5);
for (i = 0; i < 5; i++)
myvector.get_allocator().construct(&p[i], i);
cout << "The allocated array contains:";
for (i = 0; i < 5; i++)
cout << ' ' << p[i]; //[0,1,2,3,4]
for (i = 0; i < 5; i++)
myvector.get_allocator().destroy(&p[i]);
myvector.get_allocator().deallocate(p, 5);
二维数组
vector<vector<int>> arr(3);
for (int i = 0; i < 3; ++i) {
arr[i].resize(3); //3x3 array
}
for (int i = 0; i < 3; ++i)
for (int k = 0; k < 3; ++k)
arr[i][k] = i * k; // 赋值
arr.resize(4); // 二维数组包含4个变量
arr[2].resize(5); // 第3个变量包含5个变量
vector<int>price = { 1,3,8 };
vector<vector<int>>vec;
for (int i = 0; i < price.size(); i++)
{
vec.push_back({ i,price[i] });
}
for (auto it : vec)
cout << it[0] << ' ' << it[1] << endl;
vector<vector<int>> f(n, vector<int>(2));
vector< string/char >转string
#include <numeric>
vector<string>vec = { "hello ","world"};
//vector<char>vec = {'a','b','c'};
string str;
str = accumulate(vec.begin(), vec.end(),str);
cout << str;
vector< int >转string
#include <iterator>
#include <sstream>
vector<int>vec = {1,2,3};
string str;
stringstream ss;
copy(vec.begin(), vec.end(), ostream_iterator<int>(ss, ""));
str = ss.str();
cout << str;