本文主要介绍C++的STL模板中的vector的理解,主要包括常用的一些使用和三种vector的扩容方法的对比。
🎬个人简介:一个全栈工程师的升级之路!
📋个人专栏:C/C++精进之路
🎀CSDN主页 发狂的小花
🌄人生秘诀:学习的本质就是极致重复!
目录
1 vector 快速介绍
vector是C++ STL中的一个动态数组容器,相比于静态数组,vector的优势是可以动态改变其大小。C++使用时仅仅包含其头文件<vector>即可使用。
vector 是一个类模板,本质上是一个动态变长数组即顺序表,元素的类型是任意的内置或者自定义的类型,存储在连续的存储空间,访问的时间复杂度为O(1),对于尾部元素的插入和删除时间复杂度都是常量级别的。
对于vector的扩容机制,Linux一般是以2的倍数增加,VS一般是以1.5的倍数增加,增加快的性能会比较好,但是对空间的浪费会较大,一般可以使用 vec.resize(size) 进行扩容。vector扩容是开辟一段新的空间,将旧的数据拷贝到新的空间,因此对于数据量较大的场景,持续的扩容会极大的降低程序的性能。
直接可以运行的代码我放在gitee 中,一些C++例子和高性能算法
2 vector的三种扩容方法的区别
2.1 vec.resize(n)
vec.resize(n) resize的扩容不会改变容器中原来的值,这里默认对扩容的部分初始化为0
n > capacity 时 ,可以对vector进行扩容,此时 size = capacity = n,n 为任意的大于原来capacity的值
n < capacity 时,不能对vector进行扩容,此时 size = n,但是 capacity 仍然与原来的capacity 相等
2.2 vec.reserve(n)
vec.reserve(n) 是指将容器的容量改为n,容器中的数据的个数不做改变也就是,不会对vec.size() 做改变
n > capacity 时 ,可以仅仅对容器进行扩容,此时size保持不变,capacity = n
n < capacity 时 ,不做任何的改变,对size 和capacity没有任何影响
2.3 vec.assign(n,0)
vec.assign(n,0) assign的扩容会改变容器中原来的值,第二个参数就是需要改变后的值
n > capacity 时 ,可以对vector进行扩容,此时 size = capacity = n,n 为任意的大于原来capacity的值
n < capacity 时,不能对vector进行扩容,此时 size = n,但是 capacity 仍然与原来的capacity 相等
总之,对于vector容器只能增大其容量,不能减小其容量
3 vector 使用例子
#include <iostream>
#include <vector>
int main()
{
std::vector<int> vec = {1, 2, 3, 4, 5};
// vec.begin()+2 代表从第三个元素开始,vec。begin()代表从第一个元素开始
std::vector<int> vec1(vec.begin() + 2, vec.end()); // = vec
std::vector<int> vec2(vec); // = vec
std::vector<int> vec3(4); // [0,0,0,0]
std::vector<int> vec4(2, 4); // [4,4]
// vec.erase(vec.begin()+1); // 删除第二个元素
vec.erase(vec.begin(), vec.begin() + 1); // 删除[1,3) 删除两个元素
for (auto i : vec1)
{
std::cout << i << " ";
std::cout << "*******" << std::endl;
}
vec.push_back(18); // 在尾部插入一个元素
std::cout << "Front1: " << vec.front() << std::endl;
std::cout << "Back1: " << vec.back() << std::endl;
vec.pop_back(); // 弹出尾部的元素
vec.insert(vec.begin() + 4, 3, 99);
for (int i = 0; i < vec.size(); i++)
{
// std::cout << "vec(" << i << "): " << vec[i] << std::endl;
std::cout << "vec(" << i << "): " << vec.at(i) << std::endl;
}
for (int i = 0; i < vec.size(); i++)
{
std::cout << i << " : " << vec.data()[i] << std::endl;
}
std::cout << "*********" << std::endl;
std::vector<int>::iterator it;
for (it = vec.begin(); it != vec.end(); it++)
{
std::cout << " "
<< " : " << *it << std::endl;
}
std::cout << "*********" << std::endl;
for (auto it = vec.begin(); it != vec.end(); it++)
{
std::cout << " "
<< " : " << *it << std::endl;
}
std::cout << "*********" << std::endl;
// 返回常量迭代器的元素
for (auto it = vec.cbegin(); it != vec.cend(); it++)
{
std::cout << " "
<< " : " << *it << std::endl;
}
std::cout << "*********" << std::endl;
// 逆序返回常量迭代器的元素
for (auto it = vec.rbegin(); it != vec.rend(); it++)
{
std::cout << " "
<< " : " << *it << std::endl;
}
std::cout << "*********" << std::endl;
std::cout << "size: " << vec.size() << " Capacity: " << vec.capacity() << std::endl;
vec.clear();
vec.resize(16); // 可以对vector进行扩容
for (int i = 0; i < 10; i++)
{
vec.push_back(i);
} // 需要对vector进行扩容,一般扩容是2的指数级别的
std::cout << "After clear size: " << vec.size() << " Capacity: " << vec.capacity() << std::endl;
if (vec.empty())
{
std::cout << "Vec is empty!" << std::endl;
}
std::vector<int> vecT[3]; // vector 定义二维数组
for (int i = 0; i < 3; i++)
{
vecT[i].push_back(i);
std::cout << "vecT" << i << " size: " << vecT[i].size() << std::endl;
}
std::vector<std::vector<int>> vecT1; // vector 定义二维数组
vecT1.resize(5); // 5 行
for (int i = 0; i < 5; i++)
{
vecT1[i].resize(10); // 10 列
}
for (int i = 0; i < vecT1.size(); i++)
{
for (int j = 0; j < vecT1[i].size(); j++)
{
vecT1[i][j] = i * j;
}
}
for (int i = 0; i < vecT1.size(); i++)
{
for (int j = 0; j < vecT1[i].size(); j++)
{
std::cout << vecT1[i][j] << " ";
}
}
std::cout << std::endl;
return 0;
}
4 运行结果
3 *******
4 *******
5 *******
Front1: 2
Back1: 18
vec(0): 2
vec(1): 3
vec(2): 4
vec(3): 5
vec(4): 99
vec(5): 99
vec(6): 99
0 : 2
1 : 3
2 : 4
3 : 5
4 : 99
5 : 99
6 : 99
*********
: 2
: 3
: 4
: 5
: 99
: 99
: 99
*********
: 2
: 3
: 4
: 5
: 99
: 99
: 99
*********
: 2
: 3
: 4
: 5
: 99
: 99
: 99
*********
: 99
: 99
: 99
: 5
: 4
: 3
: 2
*********
size: 7 Capacity: 8
After clear size: 26 Capacity: 32
vecT0 size: 1
vecT1 size: 1
vecT2 size: 1
0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 0 2 4 6 8 10 12 14 16 18 0 3 6 9 12 15 18 21 24 27 0 4 8 12 16 20 24 28 32 36
5 vector和普通数组的区别
-
静态与动态:最显而易见的区别在于,数组的大小是静态的,这意味着一旦定义了数组的大小,就不能再更改。与此不同,vector是动态的,其大小可以在运行时进行修改,从而无需预先设定容量。
-
内存管理:数组在创建时需要在栈上或静态存储区中分配一段连续的内存空间,因此大小固定且无法更改。而vector则负责管理动态分配的内存,可以根据需要扩展或缩小内存空间。
-
性能差异:由于数组的内存分配是在编译时完成的,所以访问速度非常快。然而,如果vector需要重新分配更大的内存空间以容纳更多的元素,这个过程将涉及动态内存分配和释放,可能会比较耗时。
-
使用方法:尽管两者都支持随机访问和迭代器操作,但由于vector提供了更多的功能(如resize()、push_back()等),因此在使用时可能更为方便。
总的来说,选择使用vector还是普通数组主要取决于具体的需求和场景。例如,如果你需要一个可以动态改变大小的数据集,那么vector可能是更好的选择;反之,如果你需要一个访问速度快、大小固定的数据集,那么普通数组可能更适合你。
🌈我的分享也就到此结束啦🌈
如果我的分享也能对你有帮助,那就太好了!
若有不足,还请大家多多指正,我们一起学习交流!
📢未来的富豪们:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!最后,☺祝愿大家每天有钱赚!!!