本篇文章主要讲解vector使用的相关内容
1. vector简介
vector 是 C++ 标准库中的一个容器类模板,它提供了动态数组的功能,可以方便地管理和操作元素的集合。下面是关于 vector 的一些基本信息:
- 头文件: vector 定义在 头文件中,使用时需要包含该头文件。
- 使用命名空间: vector 类定义在 std 命名空间中,因此需要使用 std::vector 或者在代码开头添加 using namespace std; 来简化使用。
- 容器特点: vector 是一个序列式容器,它以动态数组的形式存储元素,并提供了在数组末尾快速插入和删除元素的功能。
- 元素类型: vector 可以存储几乎任何类型的元素,例如整数、浮点数、对象或其他容器,只要这些类型满足一定的要求,例如可移动构造函数和析构函数等。
- 动态大小: vector 允许动态分配和释放内存,可以根据需要动态调整大小,而无需手动管理内存。
- 访问元素: 可以使用下标运算符 [] 或者 at() 方法访问 vector 中的元素。
- 插入和删除: 可以使用 push_back() 方法将元素插入到 vector的末尾,使用 pop_back() 方法删除末尾的元素,还可以使用 insert() 方法在指定位置插入元素,使用 erase() 方法删除指定位置的元素。
- 动态调整大小: 可以使用 resize() 方法动态调整 vector 的大小,增加或减少元素数量,还可以使用 reserve() 方法预留一定的容量,避免频繁的重新分配内存。
- 遍历元素: 可以使用迭代器或者基于范围的 for 循环遍历 vector 中的元素。
- 其他操作: vector 还提供了许多其他有用的方法,例如获取大小、判断是否为空、清空容器、交换容器等。
vector 是 C++ 中常用的容器之一,它提供了灵活且高效的动态数组功能,适用于各种场景和用途。
3. vector iterator 的使用
类似的,vector的迭代器也分为正向和反向,const和非const,即
- iterator
- reverse_iterator
- const_iterator
- const_reverse_iterator
- iterator 示例
void vector_test2()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
vector<int>::iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
it = v.begin();
// 可修改
while (it != v.end())
{
++*it;
++it;
}
it = v.begin();
while (it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
- reverse_iterator 示例
void vector_test3()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
vector<int>::reverse_iterator it = v.rbegin();
while (it != v.rend())
{
cout << *it << " ";
++it;
}
cout << endl;
it = v.rbegin();
while (it != v.rend())
{
++*it;
++it;
}
it = v.rbegin();
while (it != v.rend())
{
cout << *it << " ";
++it;
}
cout << endl;
}
- const_iterator 示例
void vector_test4()
{
const vector<int> v(10,10);
vector<int>::const_iterator it = v.begin();
while (it != v.end())
{
cout << *it << " ";
++it;
}
cout << endl;
// 不可修改
/*it = v.begin();
while (it != v.end())
{
++*it;
++it;
}*/
}
- const_reverse_iterator 示例
void vector_test5()
{
const vector<int> v(10, 66);
vector<int>::const_reverse_iterator it = v.rbegin();
while (it != v.rend())
{
cout << *it << " ";
++it;
}
cout << endl;
}
3. vector 容量操作
3.1 vector 空间增长问题
对于 vector 的容量操作,重点有以下几个:
- size
- capacity
- empty
- resize
可以用以下代码查看 vector 的空间增长
void TestVectorExpand()
{
size_t sz;
vector<int> v;
sz = v.capacity();
cout << "making v grow:\n";
for (int i = 0; i < 100; ++i)
{
v.push_back(i);
if (sz != v.capacity())
{
sz = v.capacity();
cout << "capacity changed: " << sz << '\n';
}
}
}
vs下使用的STL基本是按照1.5倍方式扩容。
3.2 reserve 提前预留空间
我们知道频繁扩容会对效率大大提高,因此当我们知道需要使用多少空间的时候,应当提前预留空间,用 reserve 函数即可。
void TestVectorExpand()
{
size_t sz;
vector<int> v;
sz = v.capacity();
v.reserve(100); // 提前将容量设置好,可以避免一遍插入一遍扩容
cout << "making v grow:\n";
for (int i = 0; i < 100; ++i)
{
v.push_back(i);
if (sz != v.capacity())
{
sz = v.capacity();
cout << "capacity changed: " << sz << '\n';
}
}
}
3.3 size()、capacity()、resize()
void vector_test6()
{
vector<int> v(100, 66);
cout << v.size() << endl;
cout << v.capacity() << endl;
// 不会缩容
v.resize(50);
cout << v.capacity() << endl;
// 按照内存对齐的方式给空间
v.resize(120);
cout << v.size() << endl;
cout << v.capacity() << endl;
}
4.vector 的增删改查
注意这里的insert() 有三种重载形式,而且在算法库
iterator insert(iterator pos, const T& value);
iterator insert(iterator pos, size_type count, const T& value);
iterator insert(iterator pos, InputIterator first, InputIterator last);
- pos 是插入的位置,类型为迭代器,表示插入元素的位置。
- value 是要插入的元素值。
- count 是要插入的元素个数。
- first 和 last 是迭代器范围,表示要插入的元素序列的起始和结束位置。
void vector_test7()
{
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 << endl;
//vector<int>::iterator pos = find(v.begin(), v.end(), 3);
auto pos = find(v.begin(), v.end(), 3);
if (pos != v.end())
{
v.insert(pos, 30);
}
// 头插
v.insert(v.begin(), 0);
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
v.insert(v.begin() + 2, 0);
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
string s("abcd");
v.insert(v.begin(), s.begin(), s.end());
for (auto e : v)
{
cout << e << " ";
}
cout << endl;
}