一.vector的基本概念
vector
是C++标准库中的一种动态数组容器,提供了动态大小的数组功能,能够在运行时根据需要自动扩展和收缩。vector
以连续的内存块存储元素,可以快速访问和修改任意位置的元素。以下是
vector
的基本概念和特点:
动态大小:
vector
可以动态地调整其大小,可以在运行时根据需要添加或删除元素。与静态数组不同,vector
不需要在定义时指定固定的元素个数。连续存储:
vector
以连续的内存块存储元素。这样的存储方式使得访问元素变得高效,可以通过索引快速访问和修改任意位置的元素。自动扩展和收缩:
vector
可以根据需要自动扩展以容纳更多的元素,并在需要时自动收缩以节省内存。这样,您无需手动管理内存,vector
会自动处理。插入和删除:
vector
提供了多种方法来插入和删除元素。可以在任意位置插入元素,也可以从任意位置删除元素,包括头部和尾部。随机访问:
vector
支持快速的随机访问。可以使用索引来直接访问任意位置的元素,时间复杂度为O(1)。迭代器支持:
vector
提供迭代器来遍历容器中的元素。迭代器可以用于读取和修改容器中的元素,支持正向和反向迭代。
vector
是一个非常常用和灵活的容器,适用于需要动态调整大小的数组存储需求。它在许多应用中都很有用,例如数据的动态收集、动态分配的数组、实现栈和队列等。
功能:
vector教据结构和数组非常相似,也称为单端数组
vector与普通数组的区别
不同之处在于数组是静态空间,而vector可以动态扩展
动态扩展
并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝新空间,释放原空间
二.vector赋值操作
vector
提供了几种不同的函数和操作符用于赋值操作。以下是常用的vector
赋值操作的函数原型:
-
operator=
操作符:
vector& operator=(const vector& other);
该操作符用于将一个vector
赋值给另一个vector
,使它们包含相同的元素。该操作符返回一个引用,允许连续赋值。
-
assign()
函数:
void assign(size_type count, const T& value);
template<typename InputIt>
void assign(InputIt first, InputIt last);
void assign(std::initializer_list<T> ilist);
assign()
函数用于将指定的值、范围或初始化列表中的元素赋值给vector
。第一个版本接受指定数量的元素值;第二个版本接受范围指针,可以使用迭代器指定范围;第三个版本接受一个初始化列表。
-
swap()
函数:
void swap(vector& other);
swap()
函数用于交换两个vector
的内容,将当前vector
与另一个vector
的元素进行交换。
整理成表格,以方便查阅。
函数 | 函数原型 | 描述 |
---|---|---|
operator= |
vector& operator=(const vector& other); |
将一个vector 赋值给另一个vector ,使它们包含相同的元素。 |
assign() |
void assign(size_type count, const T& value); |
将指定数量的元素值赋值给vector 。 |
template<typename InputIt> void assign(InputIt first, InputIt last); |
将范围指针指定的元素赋值给vector 。 |
|
void assign(std::initializer_list<T> ilist); |
将初始化列表中的元素赋值给vector 。 |
|
swap() |
void swap(vector& other); |
交换两个vector 的内容。 |
三.vextor的大小和容量
vector
提供了一些函数用于获取容量和大小相关的信息。以下是vector
的容量和大小函数的原型:
-
size()
函数:
size_type size() const;
此函数返回vector
当前包含的元素数量,也就是vector
的大小。
-
max_size()
函数:
size_type max_size() const;
该函数返回vector
可以容纳的最大元素数量,考虑到系统限制和内存限制。
-
resize()
函数:
void resize(size_type count);
void resize(size_type count, const T& value);
此函数用于调整vector
的大小,可以增加或减少元素的数量。第一个版本将vector
的大小调整为指定的 count
,第二个版本还可以指定当扩展vector
大小时,默认填充的元素值。
-
capacity()
函数:
size_type capacity() const;
该函数返回当前vector
的容量,即能够在重新分配内存之前持有的元素数量,以节省内存重新分配的开销。
-
reserve()
函数:
void reserve(size_type new_cap);
此函数用于增加vector
的容量,使其至少能够容纳指定数量的元素,但不为元素分配实际值。这可以提前分配所需的内存,以减少因调整大小而引起的内存重新分配的次数。
整理成表格:
函数 | 函数原型 | 描述 |
---|---|---|
size() |
size_type size() const; |
返回vector 当前包含的元素数量,即vector 的大小。 |
max_size() |
size_type max_size() const; |
返回vector 可以容纳的最大元素数量,受系统限制和内存限制约束。 |
empty() |
bool empty() const; |
判断vector 是否为空,若为空则返回true ,否则返回false 。 |
resize() |
void resize(size_type count); void resize(size_type count, const T& value);
|
调整vector 的大小,增加或减少元素数量。第一个版本将 vector 的大小调整为指定的count 。第二个版本在扩展 vector 大小时,指定默认的填充元素值。 |
capacity() |
size_type capacity() const; |
返回当前vector 的容量,即为元素重新分配内存之前可以容纳的元素数量,以节省内存重新分配的开销。 |
reserve() |
void reserve(size_type new_cap); |
增加vector 的容量,使其至少能够容纳指定数量的元素,但不为元素分配实际值。这样可以减少内存重新分配的次数。 |
四.vector插入和删除
整理成表格:
函数 | 函数原型 | 描述 |
---|---|---|
insert() |
iterator insert(iterator pos, const T& value); iterator insert(iterator pos, size_type count, const T& value);
|
在指定位置插入元素到vector 中,并返回插入的位置迭代器。第一个版本可以插入单个元素。 第二个版本可以插入指定数量的相同元素。 |
emplace() |
template <class... Args> iterator emplace(iterator pos, Args&&... args); |
在指定位置就地构造一个元素,并返回插入的位置迭代器。 |
erase() |
iterator erase(iterator pos); iterator erase(iterator first, iterator last);
|
从vector 中删除指定位置或范围的元素,并返回下一个元素的位置迭代器。 |
clear() |
void clear(); |
从vector 中移除所有的元素,使其变为空。 |
push_back() |
void push_back(const T& value); |
将元素添加到vector 的末尾。 |
emplace_back() |
template <class... Args> reference emplace_back(Args&&... args); |
在vector 的末尾就地构造一个元素。 |
pop_back() |
void pop_back(); |
移除vector 的最后一个元素。 |
请注意,表中的函数参数使用的是迭代器(iterator),而非常数迭代器(const_iterator)。这是因为插入和删除操作会改变容器的内容,所以需要可变的迭代器来指向和修改元素。
五.vector数据的存取
下面是vector
的数据存取操作函数的函数原型整理成表格:
函数 | 函数原型 | 描述 |
---|---|---|
at() |
reference at(size_type pos); const_reference at(size_type pos) const;
|
返回指定位置的元素的引用。 若 pos 超出范围,会抛出out_of_range 异常。 |
operator[]() |
reference operator[](size_type pos); const_reference operator[](size_type pos) const;
|
返回指定位置的元素的引用。 不进行范围检查,使用时需确保索引有效。 |
front() |
reference front(); const_reference front() const;
|
返回vector 中第一个元素的引用。 |
back() |
reference back(); const_reference back() const;
|
返回vector 中最后一个元素的引用。 |
data() |
T* data(); const T* data() const;
|
返回指向vector 中第一个元素的指针。若 vector 为空,返回空指针。 |
以上是常用的vector
数据存取操作的函数原型。您可以根据需要使用它们来访问和修改vector
中的元素。
六.vector的容器交换
vector
的容器互换操作可以使用swap()
函数来实现。swap()
函数可以交换两个容器的内容,具体的函数原型如下:
template <class T, class Alloc>
void swap(vector<T,Alloc>& x, vector<T,Alloc>& y) noexcept;
其中,x
和y
是要互换内容的两个 vector
容器。使用swap()
函数可以快速高效地交换两个 vector
的内容,而不需要逐个元素进行复制或移动。
下面是一个简单的示例演示如何使用 swap()
函数交换两个 vector
的内容:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec1 = {1, 2, 3, 4};
std::vector<int> vec2 = {5, 6, 7, 8};
// 输出交换前的内容
std::cout << "vec1: ";
for (const auto& num : vec1) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "vec2: ";
for (const auto& num : vec2) {
std::cout << num << " ";
}
std::cout << std::endl;
// 交换容器内容
std::swap(vec1, vec2);
// 输出交换后的内容
std::cout << "vec1: ";
for (const auto& num : vec1) {
std::cout << num << " ";
}
std::cout << std::endl;
std::cout << "vec2: ";
for (const auto& num : vec2) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
运行以上代码,将会输出如下结果:
vec1: 1 2 3 4
vec2: 5 6 7 8
vec1: 5 6 7 8
vec2: 1 2 3 4
通过 swap()
函数,vec1
和 vec2
的内容被互换了。这个操作非常高效,因为只涉及到指针的交换,而不需要逐个元素进行复制或移动。
巧用swap收缩内存空间
swap()
函数还可以用于收缩vector
内存空间,从而释放不需要的内存。通过将一个空的vector
与目标vector
进行交换,可以使目标vector
的容量缩小到与其当前大小相匹配。
这是因为当swap()
函数交换两个vector
时,目标vector
会获得另一个vector
的内存空间,而那个被交换的vector
则会获得一个空的内存空间。然后,由于交换后的vector
大小与容量相匹配,多余的内存会被释放。
以下是一个示例代码,展示了如何通过swap()
函数收缩vector
的内存空间:
#include <iostream>
#include <vector>
int main() {
std::vector<int> vec;
// 向vector中添加大量数据
for (int i = 0; i < 1000000; ++i) {
vec.push_back(i);
}
std::cout << "Size before shrink: " << vec.size() << std::endl;
std::cout << "Capacity before shrink: " << vec.capacity() << std::endl;
// 收缩内存空间
std::vector<int>(vec).swap(vec);
std::cout << "Size after shrink: " << vec.size() << std::endl;
std::cout << "Capacity after shrink: " << vec.capacity() << std::endl;
return 0;
}
运行以上代码,将会输出如下结果:
Size before shrink: 1000000
Capacity before shrink: 1048576
Size after shrink: 1000000
Capacity after shrink: 1000000
通过使用swap()
函数将一个空的vector
和目标vector
交换,我们成功缩小了vec
的内存空间,使其容量与其大小相匹配。注意,swap()
函数的参数是通过使用临时vector
构造的,以避免影响到原始vec
的值。文章来源:https://www.uudwc.com/A/Bvja3/
请注意,这种技巧并不适用于C++11标准之前的版本,因为在C++11之前,vector
的移动语义不是必须的,而可能导致复制操作而不是交换操作。因此,在使用旧标准的编译器中,最好使用shrink_to_fit()
函数来请求收缩内存,这是C++11引入的函数,并作为标准函数来直接缩小容器的内存空间。
七.函数接口总结
以下是一些对std::vector
的扩展函数和成员类型:文章来源地址https://www.uudwc.com/A/Bvja3/
函数或成员类型 | 描述 |
---|---|
std::vector::emplace_hint |
在指定位置的提示前插入元素 |
std::vector::insert_or_assign |
插入元素或修改现有元素的值 |
std::vector::erase |
移除指定位置或指定范围的元素 |
std::vector::erase_if |
根据给定的谓词函数删除元素 |
std::vector::remove |
移除指定值的所有元素 |
std::vector::remove_if |
根据给定的谓词函数删除元素 |
std::vector::swap |
交换两个向量的内容 |
std::vector::merge |
合并两个已排序的向量,并将结果存储在第一个向量中 |
std::vector::sort |
对向量的元素进行排序 |
std::vector::stable_sort |
对向量的元素进行稳定排序 |
std::vector::reverse |
反转向量中元素的顺序 |
std::vector::unique |
移除重复的元素,仅保留相邻的一个 |
std::vector::unique |
根据给定的谓词函数移除重复的元素 |
std::vector::binary_search |
使用二分查找在排序的向量中查找元素 |
std::vector::lower_bound |
返回一个迭代器,指向在已排序向量中首次出现不小于给定值的元素位置 |
std::vector::upper_bound |
返回一个迭代器,指向在已排序向量中首次出现大于给定值的元素位置 |
std::vector::equal_range |
返回一个pair,其中第一个迭代器是lower_bound返回值,第二个迭代器是upper_bound返回值 |
std::vector::rbegin |
返回指向最后一个元素的反向迭代器 |
std::vector::rend |
返回指向第一个元素之前位置的反向迭代器 |
std::vector::cbegin |
返回指向第一个元素的常量迭代器 |
std::vector::cend |
返回指向最后一个元素之后位置的常量迭代器 |
std::vector::crbegin |
返回指向最后一个元素的反向常量迭代器 |
std::vector::crend |
返回指向第一个元素之前位置的反向常量迭代器 |
std::vector::max_size |
返回向量能容纳的最大元素数量 |
std::vector::reserve |
提前预留指定的容量,以减少重新分配内存的次数 |
std::vector::emplace_hint |
在指定位置的提示前插入元素 |
std::vector::insert_or_assign |
插入元素或修改现有元素的值 |
std::vector::get_allocator |
返回与向量关联的内存分配器 |
std::vector::operator== |
判断两个向量是否相等 |
std::vector::operator!= |
判断两个向量是否不相等 |
std::vector::operator< |
比较两个向量的字典序 |
std::vector::operator<= |
判断一个向量是否小于等于另一个向量 |
std::vector::operator> |
判断一个向量是否大于另一个向量 |
std::vector::operator>= |
判断一个向量是否大于等于另一个向量 |
std::vector::emplace_hint |
在指定位置的提示前插入元素 |
std::vector::insert_or_assign |
插入元素或修改现有元素的值 |
std::vector::erase |
移除指定位置或指定范围的元素 |
std::vector::erase_if |
根据给定的谓词函数删除元素 |
std::vector::remove |
移除指定值的所有元素 |
std::vector::remove_if |
根据给定的谓词函数删除元素 |
std::vector::swap |
交换两个向量的内容 |
std::vector::merge |
合并两个已排序的向量,并将结果存储在第一个向量中 |
std::vector::sort |
对向量的元素进行排序 |
std::vector::stable_sort |
对向量的元素进行稳定排序 |
std::vector::reverse |
反转向量中元素的顺序 |
std::vector::unique |
移除重复的元素,仅保留相邻的一个 |
std::vector::unique |
根据给定的谓词函数移除重复的元素 |
std::vector::binary_search |
使用二分查找在排序的向量中查找元素 |
std::vector::lower_bound |
返回一个迭代器,指向在已排序向量中首次出现不小于给定值的元素位置 |
std::vector::upper_bound |
返回一个迭代器,指向在已排序向量中首次出现大于给定值的元素位置 |
std::vector::equal_range |
返回一个pair,其中第一个迭代器是lower_bound返回值,第二个迭代器是upper_bound返回值 |