您好,登录后才能下订单哦!
C++标准模板库(STL)中的vector
是一个动态数组,它能够自动管理内存,并且提供了丰富的操作接口。vector
是C++中最常用的容器之一,广泛应用于各种场景中。本文将详细介绍vector
的基本使用方法,包括声明、初始化、常用操作、迭代器、容量与大小、性能分析、常见问题与解决方案以及进阶用法。
vector
是一个序列容器,它能够存储相同类型的元素,并且可以动态调整大小。与普通数组不同,vector
的大小可以在运行时动态变化,而不需要在编译时确定。vector
的内部实现是一个动态数组,它会在需要时自动分配更多的内存来存储元素。
vector
的主要特点包括:
- 动态大小:vector
的大小可以根据需要动态调整。
- 随机访问:vector
支持通过下标随机访问元素。
- 连续存储:vector
中的元素在内存中是连续存储的,这使得访问元素的速度非常快。
- 自动内存管理:vector
会自动管理内存,用户不需要手动分配和释放内存。
在使用vector
之前,需要包含头文件<vector>
。vector
的声明和初始化有多种方式,下面介绍几种常见的方式。
使用默认构造函数可以创建一个空的vector
。
#include <vector>
std::vector<int> v; // 创建一个空的int类型的vector
可以在声明时指定vector
的大小和初始值。
std::vector<int> v(10); // 创建一个大小为10的vector,所有元素初始化为0
std::vector<int> v(10, 5); // 创建一个大小为10的vector,所有元素初始化为5
可以使用初始化列表来初始化vector
。
std::vector<int> v = {1, 2, 3, 4, 5}; // 使用初始化列表初始化vector
可以使用另一个vector
来初始化新的vector
。
std::vector<int> v1 = {1, 2, 3, 4, 5};
std::vector<int> v2(v1); // 使用v1初始化v2
vector
提供了丰富的操作接口,下面介绍一些常用的操作。
push_back
push_back
函数用于在vector
的末尾添加一个元素。
std::vector<int> v;
v.push_back(1); // 添加元素1
v.push_back(2); // 添加元素2
emplace_back
emplace_back
函数与push_back
类似,但它可以直接在vector
的末尾构造元素,而不需要先创建临时对象。
std::vector<std::string> v;
v.emplace_back("hello"); // 直接在vector末尾构造一个字符串
可以通过下标访问vector
中的元素。
std::vector<int> v = {1, 2, 3, 4, 5};
int first = v[0]; // 访问第一个元素
int last = v[v.size() - 1]; // 访问最后一个元素
at
函数at
函数与下标访问类似,但它会进行边界检查,如果访问越界会抛出std::out_of_range
异常。
std::vector<int> v = {1, 2, 3, 4, 5};
int first = v.at(0); // 访问第一个元素
front
和back
函数front
函数用于访问vector
的第一个元素,back
函数用于访问vector
的最后一个元素。
std::vector<int> v = {1, 2, 3, 4, 5};
int first = v.front(); // 访问第一个元素
int last = v.back(); // 访问最后一个元素
pop_back
pop_back
函数用于删除vector
的最后一个元素。
std::vector<int> v = {1, 2, 3, 4, 5};
v.pop_back(); // 删除最后一个元素
erase
erase
函数用于删除指定位置的元素或指定范围的元素。
std::vector<int> v = {1, 2, 3, 4, 5};
v.erase(v.begin() + 2); // 删除第三个元素
v.erase(v.begin() + 1, v.begin() + 3); // 删除第二个和第三个元素
clear
clear
函数用于清空vector
中的所有元素。
std::vector<int> v = {1, 2, 3, 4, 5};
v.clear(); // 清空vector
可以通过下标或迭代器来修改vector
中的元素。
std::vector<int> v = {1, 2, 3, 4, 5};
v[0] = 10; // 修改第一个元素
v.at(1) = 20; // 修改第二个元素
find
函数find
函数用于在vector
中查找指定元素,返回指向该元素的迭代器。如果未找到,则返回end()
。
std::vector<int> v = {1, 2, 3, 4, 5};
auto it = std::find(v.begin(), v.end(), 3); // 查找元素3
if (it != v.end()) {
std::cout << "Element found: " << *it << std::endl;
} else {
std::cout << "Element not found" << std::endl;
}
count
函数count
函数用于统计vector
中指定元素的出现次数。
std::vector<int> v = {1, 2, 3, 4, 5, 3};
int cnt = std::count(v.begin(), v.end(), 3); // 统计元素3的出现次数
std::cout << "Count: " << cnt << std::endl;
vector
提供了迭代器,可以用于遍历vector
中的元素。迭代器类似于指针,可以通过解引用操作符*
来访问元素。
begin
和end
函数begin
函数返回指向vector
第一个元素的迭代器,end
函数返回指向vector
末尾的迭代器(即最后一个元素的下一个位置)。
std::vector<int> v = {1, 2, 3, 4, 5};
for (auto it = v.begin(); it != v.end(); ++it) {
std::cout << *it << " ";
}
rbegin
和rend
函数rbegin
函数返回指向vector
最后一个元素的逆向迭代器,rend
函数返回指向vector
开头的逆向迭代器(即第一个元素的前一个位置)。
std::vector<int> v = {1, 2, 3, 4, 5};
for (auto it = v.rbegin(); it != v.rend(); ++it) {
std::cout << *it << " ";
}
cbegin
和cend
函数cbegin
和cend
函数返回常量迭代器,不能通过它们修改vector
中的元素。
std::vector<int> v = {1, 2, 3, 4, 5};
for (auto it = v.cbegin(); it != v.cend(); ++it) {
std::cout << *it << " ";
}
vector
的容量(capacity)是指vector
当前分配的内存能够存储的元素数量,而大小(size)是指vector
中实际存储的元素数量。
size
函数size
函数返回vector
中实际存储的元素数量。
std::vector<int> v = {1, 2, 3, 4, 5};
std::cout << "Size: " << v.size() << std::endl;
capacity
函数capacity
函数返回vector
当前分配的内存能够存储的元素数量。
std::vector<int> v = {1, 2, 3, 4, 5};
std::cout << "Capacity: " << v.capacity() << std::endl;
resize
函数resize
函数用于调整vector
的大小。如果新的大小大于当前大小,vector
会自动添加新元素并初始化为默认值;如果新的大小小于当前大小,vector
会删除多余的元素。
std::vector<int> v = {1, 2, 3, 4, 5};
v.resize(10); // 调整大小为10,新元素初始化为0
v.resize(3); // 调整大小为3,删除多余的元素
reserve
函数reserve
函数用于调整vector
的容量。如果新容量大于当前容量,vector
会分配更多的内存;如果新容量小于当前容量,vector
不会释放内存。
std::vector<int> v = {1, 2, 3, 4, 5};
v.reserve(10); // 调整容量为10
shrink_to_fit
函数shrink_to_fit
函数用于将vector
的容量调整为与大小相同,以释放多余的内存。
std::vector<int> v = {1, 2, 3, 4, 5};
v.shrink_to_fit(); // 调整容量为与大小相同
vector
的性能主要取决于其内部实现和操作类型。下面分析几种常见操作的性能。
由于vector
中的元素在内存中是连续存储的,随机访问的时间复杂度为O(1)。
在vector
的末尾添加元素的时间复杂度为O(1),但在中间或开头添加元素的时间复杂度为O(n),因为需要移动后面的元素。
在vector
的末尾删除元素的时间复杂度为O(1),但在中间或开头删除元素的时间复杂度为O(n),因为需要移动后面的元素。
在vector
中查找元素的时间复杂度为O(n),因为需要遍历整个vector
。
vector
在需要时会自动分配更多的内存,这可能导致内存分配和复制的开销。为了避免频繁的内存分配,可以使用reserve
函数预先分配足够的内存。
访问vector
时如果下标越界,会导致未定义行为。为了避免这个问题,可以使用at
函数进行边界检查。
std::vector<int> v = {1, 2, 3, 4, 5};
try {
int value = v.at(10); // 访问越界,抛出异常
} catch (const std::out_of_range& e) {
std::cout << "Out of range: " << e.what() << std::endl;
}
vector
会自动管理内存,但在某些情况下可能会导致内存泄漏。例如,如果vector
中存储的是指针,需要手动释放指针指向的内存。
std::vector<int*> v;
v.push_back(new int(10));
v.push_back(new int(20));
// 手动释放内存
for (auto ptr : v) {
delete ptr;
}
v.clear();
在对vector
进行插入或删除操作时,可能会导致迭代器失效。为了避免这个问题,可以在操作后重新获取迭代器。
std::vector<int> v = {1, 2, 3, 4, 5};
auto it = v.begin() + 2;
v.erase(it); // 删除第三个元素,it失效
it = v.begin() + 2; // 重新获取迭代器
可以使用自定义比较函数对vector
进行排序。
std::vector<int> v = {5, 3, 1, 4, 2};
std::sort(v.begin(), v.end(), [](int a, int b) {
return a > b; // 降序排序
});
vector
存储自定义对象可以将自定义对象存储在vector
中,并对其进行操作。
class Person {
public:
std::string name;
int age;
Person(std::string name, int age) : name(name), age(age) {}
};
std::vector<Person> v;
v.emplace_back("Alice", 25);
v.emplace_back("Bob", 30);
for (const auto& person : v) {
std::cout << person.name << " " << person.age << std::endl;
}
vector
实现二维数组可以使用vector
实现二维数组。
std::vector<std::vector<int>> v(3, std::vector<int>(4, 0)); // 3行4列的二维数组
v[0][0] = 1;
v[1][1] = 2;
v[2][2] = 3;
for (const auto& row : v) {
for (int value : row) {
std::cout << value << " ";
}
std::cout << std::endl;
}
vector
是C++中最常用的容器之一,它提供了丰富的操作接口,能够满足大多数场景的需求。本文详细介绍了vector
的基本使用方法,包括声明、初始化、常用操作、迭代器、容量与大小、性能分析、常见问题与解决方案以及进阶用法。掌握vector
的使用方法,能够帮助开发者更高效地编写C++程序。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。