C++ STL - vector使用详解

目录

0.引言

1.构造函数 

2. 赋值函数

3. vector 容量与大小 

4. vector 插入和删除

5. vector 元素访问与更改

6. vector 互换 

9. vector 预留空间 


0.引言

这篇博客将详细介绍 vector,由于总体上与上一篇介绍的 string 类似,在此处注意展示其使用。关于 vector 有如下特点:

(1). vector是表示可变大小数组的序列容器。

(2). 像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素 进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自动处理。

(3). vector使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小 为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector并不会每次都重新分配大小。

(4). vector分配空间策略:vector会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是 对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。因此,vector占用了更多的存储空间,为了获得管理存储空间的能力,并且以一种有效的方式动态增 长。

(5). 与其它动态序列容器相比(deque, list and forward_list), vector在访问元素的时候更加高效,在末尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起list和forward_list 统一的迭代器和引用更好。

在 STL 中,vector 的操作有一下常用的函数,接下来我们将对其进行详细介绍:

1. vector<T> v; //T表示数据的类型,可以是int类型,也可以是string对象。
2. vector(v.begin(), v,end());  //将v[begin().end())区间(前闭后开)中的元素拷贝给本身。
3. vector(n, elem);  //构造函数将n个elem拷贝给本身。
4. vector(const vector &vec);  //拷贝构造函数。
5. vector& operator=(const vector &vec);  //重载=操作符。
6. assign(begin,end);  //将[begin,end)区间中的数据拷贝赋值给本身。
7. assign(n,elem);  //将n个elem拷贝赋值给本身。
8. empty(); //判断容器是否为空。
9. capacity(); //容器的容量。
10. size();  //返回容器中元素的个数。
11. resize(int num);  //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
                      //如果容器变短,则末尾超出容器长度的元素被删除。
12. resize(int num, elem); //重新指定容器的长度为num,若容器变成,则以elem值填充新位置。
                           //如果容器变短,则末尾超出容器长度的元素被删除。
13. push_back(ele);  //尾部插入元素ele。
14. pop_back();  //删除最后一个元素。
15. insert(const_iterator pos, ele); //迭代器指向位置pos插入元素ele。
16. insert(const_iterator pos, int count ele); //迭代器指向位置pos插入count个元素。
17. erase(const_iterator pos); //删除迭代器指向的元素。
18. erase(cons_titerator start, const_iterator end);  //删除迭代器从start到end之间的元素。
19. clear();  //删除容器中所有元素。   
20. at(int idx);   ///返回索引为idx所指的数据。
21. operator[];  //返回索引idx所指的数据。
22. front();  //返回容器中第一个数据元素。
23. back();   //返回容器中最后一个数据元素。
24. swap(vec);  //将vec与本身的元素互换。
25. reserve(int len); //容器预留len个元素长度,预留位置不初始化,元素不可访问。

1.构造函数 

 构造函数包括如下:

1. vector<T> v; //T表示数据的类型,可以是int类型,也可以是string对象
2. vector(v.begin(), v,end());  //将v[begin().end())区间(前闭后开)中的元素拷贝给本身。
3. vector(n, elem);  //构造函数将n个elem拷贝给本身
4. vector(const vector &vec);  //拷贝构造函数
void print(vector<int> v)//迭代器访问打印数据
{
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
}
vector<int> v1;//默认构造,无参创建v1对象
for (int i = 0; i < 10; i++) 
{
	v1.push_back(i);
}
print(v1);

vector<int> v2(v1.begin(), v1.end());//区间构造v2
print(v2);

vector<int> v3(10,1); //n个elem构造:此处10个1
print(v3);

vector<int> v4(v3); //拷贝构造
print(v4);

 2. 赋值函数

 赋值函数包括:

1. vector& operator=(const vector &vec);  //重载等号操作符。
2. assign(begin,end);  //将[begin,end)区间中的数据拷贝赋值给本身。
3. assign(n,elem);  //将n个elem拷贝赋值给本身。

 我们知道利用 = 重载赋值是最简单的。

vector<int> v1;//默认构造,无参创建v1对象
for (int i = 0; i < 10; i++) 
	v1.push_back(i);//尾插
print(v1);

vector<int> v2 = v1;
print(v2);

vector<int> v3;
v3.assign(v1.begin(), v1.end());
print(v3);

vector<int> v4;
v4.assign(10,1);
print(v4);

3. vector 容量与大小 

函数包括:

1. empty(); //判断容器是否为空
2. capacity(); //容器的容量
3. size();  //返回容器中元素的个数
4. resize(int num);  //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
                               //如果容器变短,则末尾超出容器长度的元素被删除。
5. resize(int num, elem); //重新指定容器的长度为num,若容器变成,则以elem值填充新位置。
                                       //如果容器变短,则末尾超出容器长度的元素被删除。

 需要注意的是:

(1). capacity表示在不分配更多内存的情况下,容器可以保存的最多元素个数。size 指的是它实际所包含的元素个数。

(2).  vector 容器的大小不能超出它的容量,在大小等于容量的基础上,只要增加一个元素,就必须分配更多的内存。此时 vector 往往会申请多个存储空间。

(3). 一旦 vector 容器的内存被重新分配,则和 vector 容器中元素相关的所有引用、指针以及迭代器,都可能会失效,最稳妥的方法就是重新生成。

vector<int> v1;//默认构造,无参创建v1对象
for (int i = 0; i < 10; i++) 
	v1.push_back(i);//尾插
print(v1);
cout << "容量:" << v1.capacity() << endl;
cout << "大小:" << v1.size() << endl;

v1.resize(20); //如果重新指定的比原来长了,默认用0填充新的位置
print(v1);

v1.resize(40,10); //如果重新指定的比原来长了,也可给定值填充新的位置
print(v1);

v1.resize(5);  //如果重新指定的比原来短了,超出的部分会删除掉
print(v1);

v1.resize(0);
if (v1.empty())
	cout << "容量为空" << endl;

 4. vector 插入和删除

1. push_back(ele);  //尾部插入元素ele
2. pop_back();  //删除最后一个元素
3. insert(const_iterator pos, ele); //迭代器指向位置pos插入元素ele
4. insert(const_iterator pos, int count, ele); //迭代器指向位置pos插入count个元素
5. erase(const_iterator pos); //删除迭代器指向的元素
6. erase(cons_titerator start, const_iterator end);  //删除迭代器从start到end之间的元素
7. clear();  //删除容器中所有元素
vector<int> v1;//默认构造,无参创建v1对象
for (int i = 0; i < 10; i++) 
	v1.push_back(i);//尾插
print(v1);

v1.pop_back();
v1.pop_back();//尾删
print(v1);

v1.insert(v1.begin(),100);//在指定位置插入数据,此处为begin
print(v1);

v1.insert(v1.begin(),2,200);//在指定位置插入数据n个元素,此处为begin,两个200
print(v1);

v1.erase(v1.begin()++);//删除第二个位置
print(v1);

v1.erase(v1.begin(),v1.end());//删除指定区间
print(v1);

v1.clear();//清空v1
print(v1);

5. vector 元素访问与更改

1. at(int idx);   ///返回索引为idx所指的数据。
2. operator[];  //返回索引idx所指的数据。
3. front();  //返回容器中第一个数据元素
4. back();   //返回容器中最后一个数据元素。
vector<int> v1;//默认构造,无参创建v1对象
for (int i = 0; i < 10; i++) 
	v1.push_back(i);//尾插

for (int i = 0; i < 10; i++)
	cout << v1.at(i) << " ";
cout << endl;

cout << "第一个元素:" << v1.front() << endl;
cout << "最后一个元素:" << v1.back() << endl;

for (int i = 0; i < 10; i++)
	cout << v1[i]*2 << " ";//[ ]最简单的访问数据方式
cout << endl;

6. vector 互换 

 实现两个容器内元素进行互换所调用的函数。

1. swap(vec);  //将vec与本身的元素互换
cout << "交换前:"<< endl;
vector<int> v1;//默认构造,无参创建v1对象
for (int i = 0; i < 10; i++) 
	v1.push_back(i);//尾插
print(v1);

vector<int> v2;//默认构造,无参创建v1对象
for (int i = 10; i < 20; i++)
	v2.push_back(i);//尾插
print(v2);

cout << "交换后:" << endl;
v1.swap(v2);
print(v1);
print(v2);

巧用 swap 可以收缩内存空间 

vector<int>v;
for (int i = 0; i < 100000; i++)
{
	v.push_back(i);
}
cout << "v的容量为:" << v.capacity() << endl;
cout << "v的大小为:" << v.size() << endl;

v.resize(3);  //重新指定大小
cout << "v的容量为:" << v.capacity() << endl;  //resize操作,容量并没有变,多余的容量浪费了
cout << "v的大小为:" << v.size() << endl;

//巧用swap收缩内存
vector<int>(v).swap(v);  
//vector<int>(v)创建了一个为匿名对象,
//会按v的大小初始化这个匿名对象容器的大小
//swap(v)会对匿名对象容器与原容器做一个交换,
//则原容器的指针指向匿名对象的容器,匿名对象的容器的指针改为指向原容器
//系统运行完创建匿名函数这一句语句后对匿名对象的指针(即地址、内存)进行回收

cout << "v的容量为:" << v.capacity() << endl;
cout << "v的大小为:" << v.size() << endl;

9. vector 预留空间 

 目的是为了减少vector在动态扩展容量时的扩展次数,提高程序运行效率。

1. reserve(int len); //容器预留len个元素长度,预留位置不初始化,元素不可访问。
vector<int>v1;
int num1 = 0;  //统计开辟次数
int* p = NULL;
for (int i = 0; i < 1000000; i++)
{
	v1.push_back(i);
	if (p != &v1[0])  //一开始指针不指向容量首地址,所以让指针指向容量首地址,开辟内存次数加1
	{
		p = &v1[0];
		num1++;   //由于容量不够,会再次开辟一段容量更大的内存空间,原小容量的内存空间被释放
	}
}
cout << "num1:" << num1 << endl;

vector<int>v2;
//预留空间
v2.reserve(1000000);
int num2 = 0;  //统计开辟次数

* p = NULL;

for (int i = 0; i < 1000000; i++)
{
	v2.push_back(i);

	if (p != &v2[0])
	{
		p = &v2[0];
		num2++;
	}
}
cout << "num2(reserve):" << num2 << endl;


vector 与  string STL接口大多是一样的,学会一个另一个的学习也会更加的轻松。  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/490722.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Python】Data Science with Python 数据科学(1)环境搭建

一、操作系统 使用运行在Windows11主机上的Ubuntu 22.04虚拟机&#xff0c;虚拟化平台为Oracle VM VirtualBox。 二、PyCharm安装 有关PyCharm的安装和快捷方式创建&#xff0c;可分别参考我的博客 Ubuntu安装PyCharm、Ubuntu创建桌面快捷方式 &#xff0c;以及Ubuntu创建桌…

Vue2(十一):全局事件总线、消息订阅与发布pubsub、TodoList的编辑功能、$nextTick、过渡与动画

一、全局事件总线 1、思路解析 一种组件间通信的方式&#xff0c;适用于任意组件间通信。通俗理解就是一个定义在所有组件之外的公共x&#xff0c;这个x可以有vm或vc上的同款$on、$off、$emit&#xff0c;也可以让所有组件都访问到。 第一个问题&#xff1a;那怎样添加这个x才…

GPU-CPU-ARM-X86-RISC-CUDA

CPU更适合处理复杂逻辑运算和单线程任务&#xff0c;而GPU则更适合处理大规模并行计算任务。 CPU&#xff08;中央处理器&#xff09;通常具有较少的核心数量&#xff08;一般在2到16个之间&#xff09;&#xff0c;但每个核心的性能较强&#xff0c;擅长执行复杂的运算和逻辑…

SpringCloud Alibaba实战和源码(8)OpenFeign使用

1、 使用Feign实现远程HTTP调用 1.1、常见HTTP客户端 HttpClient HttpClient 是 Apache Jakarta Common 下的子项目&#xff0c;用来提供高效的、最新的、功能丰富的支持 Http 协 议的客户端编程工具包&#xff0c;并且它支持 HTTP 协议最新版本和建议。HttpClient 相比传统 J…

Postman核心功能解析-参数化和测试报告

一、参数化处理 参数化&#xff1a;针对于某一个接口&#xff0c;有大量的的测试数据需要批量验证&#xff0c;一个一个的更改请求参数太耗时耗力&#xff0c;使用参数化批量处理数据会比较高效&#xff0c;常规通过文档参数化实现。 创建文件 格式CSV 文件内第一行信息 需要…

【YOLOv8代码详解】各个任务Loss损失函数梳理

YOLOv8官方将各类任务&#xff08;目标检测&#xff0c;关键点检测&#xff0c;实例分割&#xff0c;旋转目标框检测&#xff0c;图像分类&#xff09;的损失函数封装了在ultralytics\utils\loss.py中&#xff0c;本文主要梳理一下各类任务Loss的大致组成&#xff0c;不涉及到具…

封装-练习

T2、以面向对象的思想&#xff0c;编写自定义类描述IT从业者。设定属性包括&#xff1a;姓名&#xff0c;年龄&#xff0c;技术方向&#xff0c;工作年限&#xff1b;方法包括&#xff1a;工作。 要求&#xff1a; 设置属性的私有访问权限&#xff0c;通过公有的get,set方法实现…

第2章 辐射度、光度和色度学基本理论

一、前言 辐射度学&#xff08;radiology&#xff09;是一门以整个电磁波段&#xff08;electromagnetic band&#xff09;的电磁辐射能&#xff08;electromagnetic radiation energy&#xff09;测量为研究对象的科学。计算机图形学中涉及的辐射度学&#xff0c;则集中于整个…

代码随想录算法训练营三刷day35 |贪心 之 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球

三刷day35 860.柠檬水找零406.根据身高重建队列452. 用最少数量的箭引爆气球 860.柠檬水找零 题目链接 解题思路&#xff1a; 局部最优&#xff1a;遇到账单20&#xff0c;优先消耗美元10&#xff0c;完成本次找零。全局最优&#xff1a;完成全部账单的找零。 代码如下&#x…

Internet Explorer 降级

Internet Explorer 降级 1. version2. Internet Explorer 降级References 1. version 帮助 -> 关于Internet Explorer(A) 2. Internet Explorer 降级 开始 -> 控制面板 -> 卸载程序 -> 查看已安装的更新 搜索 Internet -> Internet Explorer 11 -> 卸载 -…

office办公技能|word中的常见使用问题解决方案2.0

一、设置多级列表将表注从0开始&#xff0c;设置为从1开始 问题描述&#xff1a;word中插入题注&#xff0c;出来的是表0-1&#xff0c;不是1-1&#xff0c;怎么办&#xff1f; 写论文时&#xff0c;虽然我设置了“第一章”为一级标题&#xff0c;但是这三个字并不是自动插入的…

[leetcode]118.杨辉三角

前言&#xff1a;剑指offer刷题系列 问题&#xff1a; 给定一个非负整数 *numRows&#xff0c;*生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例&#xff1a; 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,…

C# NumericUpDown 控件正整数输入控制

用到了控件的 KeyPress 和 KeyUp事件。 KeyPress 中控制输入“点、空格&#xff0c;负号”&#xff1b; KeyUp 中防止删空&#xff0c;以及防止输入超过最大值或最小值 。 private void nudStart_KeyPress(object sender, KeyPressEventArgs e){numericUpDownKeyPress(sender…

CAPL - 如何实现弹窗提示和弹窗操作(续)

目录 函数介绍 openPanel closePanel 代码示例 1、简单的打开关闭panel面板

美团0309春招笔试题

下面是美团2024-03-09笔试真题&#xff0c;笔者进行了VP&#xff0c;由于未参与评测&#xff0c;故不保证正确性&#xff0c;仅供参考。 第一题 小美的MT 首先找到原来字符串中含有的M和T的数量&#xff0c;记作cnt。然后剩余n - cnt个字符是可以修改的&#xff0c;但这取决于…

二叉树|236.二叉树的最近公共祖先

力扣题目链接 class Solution { public:TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {if (root q || root p || root NULL) return root;TreeNode* left lowestCommonAncestor(root->left, p, q);TreeNode* right lowestCommonAncesto…

【办公类-21-10】三级育婴师 视频转文字docx(等线小五单倍行距),批量改成“宋体小四、1.5倍行距、蓝色字体、去掉五分钟”

作品展示 背景需求 今天将最后3个育婴师操作视频做整理 第1步&#xff1a;视频MP4转MP3 【办公类-40-01】20240311 用Python将MP4转MP3提取音频 &#xff08;家长会系列一&#xff09;-CSDN博客文章浏览阅读393次&#xff0c;点赞9次&#xff0c;收藏6次。【办公类-40-01】20…

鸿蒙应用开发-录音保存并播放音频

功能介绍&#xff1a; 录音并保存为m4a格式的音频&#xff0c;然后播放该音频&#xff0c;参考文档使用AVRecorder开发音频录制功能(ArkTS)&#xff0c;更详细接口信息请查看接口文档&#xff1a;ohos.multimedia.media (媒体服务)。 知识点&#xff1a; 熟悉使用AVRecorder…

码垛机与人工搬运:效率与安全性的比较分析

在现代包装行业中&#xff0c;泡沫箱因其轻便和保温特性被广泛用于商品的包装与运输。随着自动化技术的不断发展&#xff0c;码垛机成为提升泡沫箱生产效率、降低劳动强度的关键技术。本文旨在比较码垛机与人工码垛在泡沫箱生产中的优势&#xff0c;并探讨自动化码垛的未来发展…