您好,登录后才能下订单哦!
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_backpush_back函数用于在vector的末尾添加一个元素。
std::vector<int> v;
v.push_back(1); // 添加元素1
v.push_back(2); // 添加元素2
emplace_backemplace_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_backpop_back函数用于删除vector的最后一个元素。
std::vector<int> v = {1, 2, 3, 4, 5};
v.pop_back(); // 删除最后一个元素
eraseerase函数用于删除指定位置的元素或指定范围的元素。
std::vector<int> v = {1, 2, 3, 4, 5};
v.erase(v.begin() + 2); // 删除第三个元素
v.erase(v.begin() + 1, v.begin() + 3); // 删除第二个和第三个元素
clearclear函数用于清空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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。