C++初阶:STL详解(三)——vector的介绍和使用

✨✨小新课堂开课了,欢迎欢迎~✨✨

🎈🎈养成好习惯,先赞后看哦~🎈🎈

所属专栏:C++:由浅入深篇

小新的主页:编程版小新-CSDN博客

前言:

前面我们刚刚了解了string类的使用和模拟实现,当对string有了一定的了解后,再来看vector的使用和后面要提到模拟实现是很好上手的。

C++初阶:STL详解(一)——string类-CSDN博客

C++初阶:string类的模拟实现-CSDN博客

一.什么是vector?

vector(向量)是C++标准库中的一种序列容器,它是一种非常常用的动态数组实现。可以高效的存储和访问一组相同类型的元素,能够自动管理储存,可动态增长或收缩。

 vector是一个模板类,定义在头文件(include<vector>)中,可以使用vector来存储和访问任意类型的对象。

二.vector的特性

1.动态数组:可以动态地增加和减少数组元素,自动管理内存分配和释放,不需要手动进行内存操作。

2.高效随机访问:支持随机访问

3.连续存储:元素在内存中连续存储

4.支持插入和删除:在尾部或头部插入和删除元素通常是高效的,但是其他位置的效率较低。

5.丰富的接口:提供了多种成员函数,如push_back,pop_back,insert,erase等,方便进行各种操作。

三.vector的文档介绍 

vector - C++ Reference(英文版)

std::vector - cppreference.com(中文版)

四.vector的使用

vector 在实际中非常的重要,在实际中我们熟悉常见的接口就可以,下面列出了哪些接口是要重点掌握的 。我们在后面模拟实现的时候,也是实现这些常见的接口。

4.1vector的定义

(constructor)构造函数声明接口说明
vector()(重点)无参构造
vector(size_type n, const value_type& val = value_type())构造并初始化n个val

vector (const vector& x); (重点)

拷贝构造

vector (InputIterator first, InputIterator last);使用迭代器进行初始化构造

1.vector(): 构造一个空vector

vector<int> v1;//构造一个int 类型的空容器

2.vector(size_type n, const value_type& val = value_type()):构造一个vector,元素个数为n,元素为value_type()

vector<int> v2(10, 1);//构造一个含有10个1的int类型容器

vector<char> v5(10, 'c'); //构造一个含有10个c的char类型容器

3. vector (const vector& x) :拷贝构造

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

4.vector (InputIterator first, InputIterator last) :使用迭代器区间进行初始化构造

vector<int> v4(v2.begin(), v2.end());//使用迭代器区间拷贝构造v2容器的一部分

4.2vector的空间增长问题

容量空间接口说明

size获取数据个数

capacity获取容量大小

empty判断是否为空

resize(重点)改变vector的size

reserve (重点)改变vector的capacity

size和capacity

void vector2()
{
	vector<int> v1(10, 1);

	cout << "size:" << v1.size() << endl;//获取当前容器有效元素的个数

	cout << "capacity:" << v1.capacity() << endl;//获取当前容器的容量大小

}

运行结果:

小扩展:

我们在说string类的时候,也提到过。capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是2倍增长的。这个问题经常会考察,不要固化的认为,vector增容都是2倍,具体增长多少根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。

empty

用于判断当前容器是否为空,true:返回非0(一般是1):;false:返回0。

void vector2()
{
	vector<int> v1(10, 1);

	cout << v1.empty() << endl;
}

运行结果:0

resize和reserve

resize函数改变容器中的有效元素个数,reserse函数改变容器的容量。

resize规则:
 1、当所给值大于容当前容器的size时,将size扩大到该值,扩大的元素为第二个所给值,若未给出,则int型默认为0,char型默认是'\0'。

   2、当所给值小于容器当前的size时,将size缩小到该值。

reserve规则:
 1、当所给值大于当前容器的capacity时,将capacity扩大到该值。
 2、当所给值小于当前容器的capacity时,什么也不做,不会缩容。

void vector2()
{

    vector<int> v(10, 1);
	cout << "size:" << v.size() << endl;
    cout << "capacity:" << v.capacity() << endl;

	v.reserve(20);//改变当前容器的容量为20
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;

	v.resize(5);//改变当前容器的size为5
	cout << "size:" << v.size() << endl;
	cout << "capacity:" << v.capacity() << endl;

}

运行结果:

注意:reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。resize在开空间的同时还会进行初始化,影响size。

4.3vector迭代器的使用

iterator的使用接口说明
begin + end(重点)begin获取第一个数据位置的iterator/const_iterator, end获取最后一个数据的下一个位置的iterator/const_iterator
rbegin + rendrbegin获取最后一个数据位置的reverse_iterator,rend获取第一个数据前一个位置的reverse_iterator
 

void vector3()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };

	vector<int> v(begin(arr), end(arr));//C++11将一个整形数组装换为vector

	//正向迭代器进行遍历
	cout << "正向迭代器遍历:";
	vector<int>:: iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		it++;
	}

	cout << endl;

	//反向迭代器遍历
	cout << "反向迭代器遍历:";
	vector<int>::reverse_iterator rit = v.rbegin();
	while (rit != v.rend())
	{
		cout << *rit << " ";
		rit++;
	}

	cout << endl;

}

运行结果:

除了上面遍历的方式,我们知道支持迭代器就支持范围for,因此我们也可以使用范围for对容器进行遍历。

void vector3()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };

	vector<int> v(begin(arr), end(arr));//C++11将一个整形数组装换为vector

	for (auto ch : v)
	{
		cout << ch << " ";
	}

}

运行结果:

4.4vector的增删查改

vector增删查改接口说明
push_back(重点)尾插
pop_back (重点)尾删
find查找。(注意这个是算法模块实现,不是vector的成员接口)
insert在position之前插入val
erase删除position位置的数据
swap交换两个vector的数据空间
operator[] (重点)像数组一样访问

push_back 和 pop_back

void vector4()
{
	vector<int> v;
	v.push_back(1);//尾插
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	v.pop_back();//尾删

	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		it++;
	}

}

运行结果:

find

find:
template <class InputIterator, class T>
   InputIterator find (InputIterator first, InputIterator last, const T& val)

find函数有三个参数,前两个参数确定了一个迭代器区间(左闭右开),第三个参数确定所要寻找的值。find函数在所给迭代器区间寻找第一个匹配的元素,并返回它的迭代器,若未找到,则返回所给的第二个参数。 

insert和erase 

void vector4()
{
	vector<int> v;
	v.push_back(1);//尾插
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);

	vector<int>:: iterator pos = find(v.begin(), v.end(), 3);//返回元素为3位置的迭代器

	v.insert(pos, 8);//在pos位置插入一个8

	pos = find(v.begin(), v.end(), 4);

	v.erase(pos);//删除pos位置的元素
	
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		it++;
	}

	cout << endl;
	
}

运行结果:

swap

swap函数可以交换两个容器的数据空间,实现两个容器的交换。

void vector5()
{
	vector<int> v1(10, 1);
    vector<int> v2(5, 2);

	cout << "交换前:" << endl;
	cout << "v1:" << v1.size() <<" "<< v1.capacity() << endl;
	cout << "v2:" << v2.size() <<" "<< v2.capacity() << endl;

	swap(v1,v2);

	cout << "交换后:" << endl;
	cout << "v1:" << v1.size() <<" "<< v1.capacity() << endl;
	cout << "v2:" << v2.size() << " "<<v2.capacity() << endl;
}

运行结果:

operator[]

vector当中实现了 [ ] 操作符的重载,因此我们也可以通过“下标+[ ]”的方式对容器当中的元素进行访问。当然也可以对其进行修改。

void vector6()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };

	vector<int> v(begin(arr), end(arr));//C++11将一个整形数组装换为vector

	for (int i = 0; i < v.size(); i++)
	{
		v[i] += 2;
		cout << v[i] << " ";
	}
	cout << endl;
}

运行结果:

 不知不觉中,我们就已经知道了四种遍历容器的方式了:下标+[]/正向迭代器/反向迭代器/范围for。

总结:

以上就是对vector及其常见接口的介绍,这里还有一个经典的迭代器失效的问题,我们后面讲,vector的难点在于模拟实现,这个放在迭代器失效问题之后也会讲。

感谢大家的观看,创作不易,还请各位大佬点赞支持~

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

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

相关文章

Jetpack Compose Side Effects in Details 副作用的详细信息

What is Side Effect’s? 副作用是什么&#xff1f; Side Effects is a change in the state of the application that occurs outside the scope of the composable function and is not related to the UI. In non-UI related state changes, our screen may recompose mor…

【C语言零基础入门篇 - 6】:数组、字符和字符串带你探索无限可能

文章目录 数组一维数组一维数组的定义一维数组的初始化 字符数组二维数组二维数组存汉字 字符串相关函数小结 数组 特点&#xff1a; 在同一个数组中&#xff0c;所有元素都是同一个类型。可以是int、char、float、double等类型。数组是一种构造类型&#xff0c;是一批数据的…

PCIe进阶之TL:Completion Rules TLP Prefix Rules

1 Completion Rules & TLP Prefix Rules 1.1 Completion Rules 所有的 Read、Non-Posted Write 和 AtomicOp Request 都需要返回一个 Completion。Completion 有两种类型:一种带数据负载的,一种不带数据负载的。以下各节定义了 Completion header 中每个字段的规则。 C…

腾讯百度阿里华为常见算法面试题TOP100(3):链表、栈、特殊技巧

之前总结过字节跳动TOP50算法面试题: 字节跳动常见算法面试题top50整理_沉迷单车的追风少年-CSDN博客_字节算法面试题 链表 160.相交链表

基于python+django+vue的外卖管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于pythondjangovueMySQL的外…

word文档无损原样转pdf在windows平台使用python调用win32com使用pip安装pywin32

前提&#xff1a; windows环境下&#xff0c;并且安装了office套装&#xff0c;比如word,如果需要调用excel.也需要安装。在另外的文章会介绍。这种是直接调用word的。所以还原度会比较高。 需求&#xff1a; word文档转pdf,要求使用命令行形式&#xff0c;最终发布为api接口…

通过sshd_config限制用户登录

在CentOS Stream或其他现代的Linux发行版中&#xff0c;你可能会发现传统的hosts.deny和 hosts.allow文件已经不存在或不被使用。这是因为随着时间的推移&#xff0c;系统的安全策略和网络管理工具已经发生了演变&#xff0c;许多系统管理员和发行版维护者选择使用更现代、更灵…

鸿蒙next web组件和h5 交互实战来了

前言导读 鸿蒙next web组件这个专题之前一直想讲一下 苦于没有时间&#xff0c;周末把代码研究的差不多了&#xff0c;所以就趁着现在这个时间节点分享给大家。也希望能对各位读者网友工作和学习有帮助&#xff0c;废话不多说我们正式开始。 效果图 默认页面 上面H5 下面ArkU…

小米,B站网络安全岗位笔试题目+答案

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

开源免费的工贸一体行业ERP管理系统

引言 在当今数字化浪潮汹涌澎湃的时代&#xff0c;中小企业面临着前所未有的挑战与机遇。如何实现数字化转型发展&#xff0c;成为了众多中小企业主心头的大事。 据相关数据显示&#xff0c;目前我国中小企业数量已经超过了 4000 万户&#xff0c;然而成功实现数字化转型的比例…

.NET 一款免杀的白名单工具可执行系统命令

01阅读须知 此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失&#xf…

使用Mockito进行单元测试

1、单元测试介绍 Mockito和Junit是用于单元测试的常用框架。单元测试即&#xff1a;从最小的可测试单元&#xff08;如函数、方法或类&#xff09;开始&#xff0c;确保每个单元都能按预期工作。单元测试是白盒测试的核心部分&#xff0c;它有助于发现单元内部的错误。 单元测试…

【AcWing 158周赛】

5842. 拆树 主要思路&#xff1a; 如何分割&#xff1f; 深度遍历&#xff0c;当遍历的子数的sum为总sum的三分之一即是一个分割方法。 1其中要注意节点范围为 [ − 100 &#xff0c; 100 ] [-100&#xff0c;100] [−100&#xff0c;100],所以当 总树 s u m 0 总树sum0 总树…

算法:30.串联所有单词的子串

题目 链接&#xff1a;leetcode链接 思路分析&#xff08;滑动窗口&#xff09; 这道题目类似寻找异位词的题目&#xff0c;我认为是寻找异位词的升级版 传送门:寻找异位词 为什么说像呢&#xff1f; 注意&#xff1a;这道题目中words数组里面的字符串长度都是相同的&…

C语言-数据结构 弗洛伊德算法(Floyd)邻接矩阵存储

弗洛伊德算法相比迪杰斯特拉相似的地方都是遍历邻接矩阵不断调整最短路径的信息&#xff0c;并且两种算法面对多源最短路径的时间复杂度都是O(n^3)&#xff0c;Floyd采用的是动态规划而Dijkstra是采用贪心的思想。在Floyd中我们将创建两个数组进行辅助&#xff0c;一个path二维…

sqlgun靶场训练

1.看到php&#xff1f;id &#xff0c;然后刚好有个框&#xff0c;直接测试sql注入 2.发现输入1 union select 1,2,3#的时候在2处有回显 3.查看表名 -1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schemadatabase()# 4.查看列名…

磁盘写入缓存区太大,如何清理C盘缓存

针对“磁盘写入缓存区太大&#xff0c;如何清理C盘缓存”的问题&#xff0c;我们可以从多个角度进行专业解答。首先&#xff0c;需要明确的是&#xff0c;“磁盘写入缓存区太大”这一表述可能涉及硬盘缓存的设置或系统缓存管理&#xff0c;但通常用户面对的问题更多是关于C盘空…

极速上云2.0范式:一键智连阿里云

在传统上云的现状与挑战&#xff1a; 专线上云太重&#xff0c;VPN上云不稳&#xff0c;云上VPC&#xff0c;云下物理网络&#xff0c;多段最后一公里...... 层层对接&#xff0c;跳跳延迟&#xff0c;好生复杂! 当你试图理解SD-WAN供应商和阿里云的文档&#xff0c;以协调路由…

【23-24年】年度总结与迎新引荐

文章目录 相关连接前言1 忙碌的备研与本科毕设2 暑期阿里之旅3 团队荣誉与迎新引荐4 项目合作意向 相关连接 个人博客&#xff1a;issey的博客 - 愿无岁月可回首 前言 自从2023年4月更新了两篇关于NLP的文章后&#xff0c;我便消失了一年半的时间。如今&#xff0c;随着学业…

[000-01-008].第05节:OpenFeign特性-重试机制

我的后端学习大纲 SpringCloud学习大纲 1.1.重试机制的默认值&#xff1a; 1.重试机制默认是关闭的&#xff0c;给了默认值 1.2.测试重试机制的默认值&#xff1a; 1.3.开启Retryer功能&#xff1a; 1.修改配置文件YML的配置&#xff1a; 2.新增配置类&#xff1a; packa…