文档:vector
文章目录
- 0. 前言
- 1. 构造函数
- 2. 迭代器
- 3. 容量接口
- 4. 元素访问
- 5.元素修改
- 尾插尾删
- 指定位置添加&删除
vector
是一种动态数组,可以在元素添加或删除时自动调整大小。它是C++标准模板库(STL) 的一部分,使用模板类实现,定义在
头文件中
explicit vector (const allocator_type& alloc = allocator_type());
explicit vector (size_type n, const value_type& val = value_type(),
const allocator_type& alloc = allocator_type());
template <class InputIterator>
vector (InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type()); //模板迭代器
vector (const vector& x);
使用示例:
void test1()
{
//创建10个整型的vector,默认初始化为0
vector<int> v1(10);
//创建包含5个整型的vector,将所有元素初始化为1
vector<int> v2(10,1);
//迭代器初始化
vector<int> v3(v2.begin(),v2.end());
string s("hello");
vector<char> v4(s.begin(),s.end());
//拷贝构造
vector<int> v5(v2);
}
名称 | 功能 |
---|---|
begin |
返回指向容器起始位置(第一个元素)的迭代器 |
end |
返回指向容器结束位置(最后一个元素后面一个位置)的迭代器 |
rbegin |
返回指向容器的反向起始位置(最后一个元素)的反向迭代器 |
rend |
返回指向容器的反向结束位置(第一个元素前面一个位置)的反向迭代器 |
cbegin |
返回指向容器起始位置(第一个元素)的常量迭代器。该迭代器不允许修改容器的元素 |
cend |
返回指向容器结束位置(最后一个元素后面一个位置)的常量迭代器。该迭代器不允许修改容器的元素 |
crbegin |
返回指向容器的反向起始位置(最后一个元素)的常量反向迭代器 |
crend |
返回指向容器的反向结束位置(第一个元素前面一个位置)的常量反向迭代器 |
迭代器可以配合算法使用
void t2()
{
vector<int> v1;
v1.push_back(2);
v1.push_back(0);
v1.push_back(2);
v1.push_back(3);
v1.push_back(7);
v1.push_back(1);
v1.push_back(9);
//排序算法 升序
sort(v1.begin(), v1.end());
for (auto e : v1)
{
cout << e << "";
}
cout << endl;
string s("hello");
vector<char>v2(s.begin(), s.end());
sort(v2.begin(), v2.end());
for (auto e : v2)
{
cout << e << " ";
}
cout << endl;
}
接口 | 功能 |
---|---|
size |
容器中元素的数量 |
max_size |
容器能包含的最大元素数量(不同平台有所不同) |
resize |
改变容器中元素的数量 |
capacity |
返回当前所分配内存空间的大小 |
empty |
检测容器中是否有元素(无返回true,有返回false) |
reserve |
申请改变容量 |
shrink_to_fit |
收缩至合适大小 |
这些设置,其实都是大同小异,但要注意使用场景
比如:
void t3()
{
vector<int> v1; //未初始化
v1.reserve(10);
for (size_t i = 0; i < 10; i++)
{
//会自己增加size
v1.push_back(i);
cout << v1[i] << " ";
}
cout << endl;
vector<int> v2;
//提前开好size空间
v2.resize(10);
for (size_t i = 0; i < 10; i++)
{
v2[i] = i;
cout << v2[i] << " ";
}
cout << endl;
}
vector
的扩容和string
一样,Vs2022为1.5倍扩容,Linux环境gcc/g++则是2倍扩容
这里[]
访问,和at
访问有一个区别就是:[]
如果越界访问是断言,而at
是抛异常
接口 | 功能 |
---|---|
assign |
用新元素更好容器中的内容 |
push_back |
尾插 |
pop_back |
尾删 |
insert |
指定位置插入 |
erase |
指定位置删除 |
swap |
交换2个容器中的内容 |
clear |
清理容器 |
emplace |
在容器中的指定位置构造新元素。与insert() 不同的是,emplace() 允许直接在容器中构造元素,而不需要通过拷贝或移动元素。 |
emplace_back |
在容器的末尾构造新元素。与push_back() 类似,但是emplace_back() 允许直接在容器中构造元素,而不需要通过拷贝或移动元素。 |
这里发现,不管是string
和vector
都没有提供头插头删,因为这两个的本质上可以看作顺序表,顺序表的头插头删效率都是十分低下的。所以只提供了尾插尾删
void t4()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
for (auto e : v)
{
cout << e << " ";
}
cout << '\n';
v.pop_back();
v.pop_back();
for (auto e : v)
{
cout << e << " ";
}
cout << '\n';
}
指定位置添加或者删除元素,就可以勉强认为实现了头插头删
void t5()
{
int arr[] = { 1,2,3,4,5,6,7,8 };
vector<int> v(arr, arr + sizeof(arr) / sizeof(int));
v.insert(v.begin()+1, 22);
v.erase(v.begin()+5);
for (auto e : v)
{
cout << e << " ";
}
cout << '\n';
}
这里面,没有查找功能,因为vector
的定义是一个类模板,要和其他容器复用,C++标准库里面有find
算法,所有就没必要再写了,但我们也可以手搓一个
void t6()
{
int arr[] = { 2,0,2,3,7,19,22,50,2 };
vector<int> v(arr, arr + sizeof(arr) / sizeof(int));
//查找所有为2的数据,并将其删除
vector<int>::iterator pos = std::find(v.begin(), v.end(), 2);
while (pos != v.end())
{
v.erase(pos);
pos = std::find(v.begin(), v.end(), 2);
}
for (auto e : v)
{
cout << e << " ";
}
cout << '\n';
}
学习了string
类,再来学习vector
就相对轻松一点,都是大同小异,vector
的设计相比string
就没那么冗余,详细的学习可以去官网查看文档
那本期的分享就到这里,我们下期再见,如果还有下期的话