vector
(向量)是C++标准模板库(STL)中最常用的容器之一,它提供了动态数组的功能,可以存储任意类型的元素。vector
具有自动管理内存、支持随机访问、动态调整大小等优点,非常适合用于需要频繁增删元素或未知大小的数组场景。下面是对vector
的总结和常见用法。
先复习一下c++中常用的构造函数,构造函数可以分为无参构造函数(默认构造函数),有参构造函数,拷贝构造函数,以及移动构造函数;
一、vector
的特点
-
动态大小:
vector
可以根据需要动态调整自身的大小,自动管理内存。 -
连续存储:
vector
在内存中以连续的方式存储元素,支持随机访问,效率高。 -
自动内存管理:当元素增加超出容量时,
vector
会自动分配更多内存。 -
丰富的成员函数:提供了插入、删除、访问、遍历等一系列方便的操作函数。
二、vector
的常见操作
-
定义和初始化
#include <vector> // 定义一个空的int类型vector vector<int> vec1; // 使用初始大小和默认值 vector<int> vec2(10); // 大小为10,默认值为0 vector<int> vec3(5, 1); // 大小为5,所有元素初始化为1 // 使用列表初始化 vector<int> vec4 = {1, 2, 3, 4, 5};
-
添加元素
vec1.push_back(10); // 在末尾添加元素10 vec1.emplace_back(20); // 在末尾直接构造元素20(效率更高)
面试常问两者的区别
-
访问元素
int value = vec4[2]; // 使用下标访问(不进行边界检查) int value = vec4.at(2); // 使用at函数访问(进行边界检查) int front = vec4.front(); // 获取第一个元素 int back = vec4.back(); // 获取最后一个元素
-
删除元素
vec4.pop_back(); // 删除最后一个元素 vec4.erase(vec4.begin() + 2); // 删除指定位置的元素 vec4.clear(); // 清空所有元素
-
插入元素
vec4.insert(vec4.begin() + 1, 100); // 在第二个位置插入100
-
遍历元素
// 使用索引 for (size_t i = 0; i < vec4.size(); ++i) { cout << vec4[i] << " "; } // 使用迭代器 for (auto it = vec4.begin(); it != vec4.end(); ++it) { cout << *it << " "; } // 使用范围for循环(C++11及以上) for (const auto& val : vec4) { cout << val << " "; }
-
容量和大小
size_t size = vec4.size(); // 获取元素数量 size_t capacity = vec4.capacity(); // 获取当前容量 bool empty = vec4.empty(); // 判断是否为空 vec4.reserve(100); // 预留空间,避免频繁分配内存 vec4.shrink_to_fit(); // 释放多余的内存
-
容量和大小的调整
resize函数,调整vector元素的大小;
#include <vector> #include <iostream> int main() { std::vector<int> vec = {1, 2, 3}; // 将大小调整为 5,新增元素默认初始化为 0(int 类型) vec.resize(5); // vec 现在是 {1, 2, 3, 0, 0} // 将大小缩小为 2,最后两个元素被删除 vec.resize(2); // vec 现在是 {1, 2} return 0; }
reserve()函数,改变容量capcity,即预先分配的内存大小。
#include <vector> #include <iostream> int main() { std::vector<int> vec; // 预留容量为 10,不改变当前的大小 vec.reserve(10); std::cout << "Capacity: " << vec.capacity() << ", Size: " << vec.size() << std::endl; // 输出: Capacity: 10, Size: 0 // 添加元素后,大小增加,容量不变 vec.push_back(1); std::cout << "Capacity: " << vec.capacity() << ", Size: " << vec.size() << std::endl; // 输出: Capacity: 10, Size: 1 return 0; }
三、在示例代码中的应用
在之前提供的岛屿数量的算法中,vector
被用于表示二维网格:
vector<vector<char>> grid;
-
表示二维数组:
vector
可以嵌套,形成二维甚至多维数组,方便地表示矩阵或网格。 -
动态调整大小:在处理未知大小的网格时,
vector
能够根据输入的数据动态调整大小,无需提前指定固定的数组大小。 -
方便的访问和修改:通过
grid[i][j]
的方式,可以方便地访问和修改网格中的元素。
四、注意事项
-
效率考虑:频繁插入或删除操作,尽量在末尾进行,避免移动大量元素。如果需要在中间进行频繁插入删除,可以考虑使用
list
或deque
。 -
边界检查:使用
operator[]
访问元素时,不进行边界检查,可能导致越界访问。为了安全,建议使用at()
函数。 -
内存管理:
vector
会自动管理内存,但有时可能会占用比实际需要更多的内存,可以使用shrink_to_fit()
来释放未使用的容量。
五、常用成员函数
-
构造函数
vector(); // 默认构造函数 vector(size_type n); // 指定大小,默认值初始化 vector(size_type n, const T& value); // 指定大小和初始值 vector(const vector& other); // 拷贝构造函数 vector(vector&& other); // 移动构造函数
-
赋值操作
vec.assign(n, value); // 赋值n个value vec.assign(first, last); // 赋值迭代器范围内的值 vec = other_vec; // 赋值操作符
-
元素访问
vec[i]; // 访问第i个元素 vec.at(i); // 访问第i个元素,带边界检查 vec.front(); // 第一个元素 vec.back(); // 最后一个元素 vec.data(); // 返回指向数组首元素的指针
-
修改容器
vec.push_back(value); // 在末尾添加元素 vec.pop_back(); // 删除末尾元素 vec.insert(pos, value); // 在指定位置插入元素 vec.erase(pos); // 删除指定位置的元素 vec.clear(); // 清空所有元素 vec.resize(n); // 调整大小为n vec.reserve(n); // 预留容量为n
-
容量相关
vec.size(); // 返回元素数量 vec.capacity(); // 返回当前容量 vec.empty(); // 判断是否为空 vec.max_size(); // 返回最大可能存储的元素数量 vec.shrink_to_fit(); // 释放未使用的内存
-
迭代器
vec.begin(); // 指向第一个元素的迭代器 vec.end(); // 指向最后一个元素之后的迭代器 vec.rbegin(); // 反向迭代器,指向最后一个元素 vec.rend(); // 反向迭代器,指向第一个元素之前
六、vector
与数组的区别
-
大小可变:
vector
的大小可以动态变化,而数组的大小固定。 -
类型安全:
vector
是模板类,可以存储任意类型的元素,并且支持类型检查。 -
功能丰富:
vector
提供了大量成员函数,支持各种操作。 -
内存连续:与数组一样,
vector
在内存中也是连续存储,支持高效的随机访问。
七、总结
vector
是C++中功能强大且常用的容器,适用于需要动态数组的场景。在使用vector
时,应注意效率和安全性,合理地选择成员函数和操作方式。通过熟练掌握vector
的用法,可以大大提高编程效率和代码质量。
标签:容器,STL,元素,vec4,vector,vec,大小,构造函数 From: https://blog.csdn.net/qq_45993770/article/details/142281080