C++STL初阶(4):初识vector

       vector是一个类模版,是一个顺序容器,底层思维就是顺序表,而顺序表的本质就是一个可以改变size的数组。本篇基于string的学习基础,我们对vector进行一个大致的了解和学习


1.基本介绍

1. vector 是表示可变大小数组的序列容器,几乎所有类型都可以成为vector的元素,因此vector也可以进行嵌套,如:vector<vector<int>>
2.  就像数组一样, vector 也采用的连续存储空间来存储元素。也就是意味着可以采用下标对 vector 的元素 进行访问,和数组一样高效。但是又不像数组,它的大小是可以动态改变的,而且它的大小会被容器自 动处理。
3. 与其他动态容器的使用区别 与其它动态序列容器相比( deque, list and forward_list ), vector 在访问元素的时候更加高效,在末 尾添加和删除元素相对高效。对于其它不在末尾的删除和插入操作,效率更低。比起 list forward_list 统一的迭代器和引用更好
4. 时间和空间的使用
vector 使用动态分配数组来存储它的元素。当新元素插入时候,这个数组需要被重新分配大小 ,为了增加存储空间。其做法是,分配一个新的数组,然后将全部元素移到这个数组。就时间而言,这是一个相对代价高的任务,因为每当一个新的元素加入到容器的时候,vector 并不会每次都重新分配大小。
 vector 分配空间策略: vector 会分配一些额外的空间以适应可能的增长,因为存储空间比实际需要的存 储空间更大。不同的库采用不同的策略权衡空间的使用和重新分配。但是无论如何,重新分配都应该是 对数增长的间隔大小,以至于在末尾插入一个元素的时候是在常数时间的复杂度完成的。

 2.vector基础操作 

2.1构造函数 

      正如上文所说,vector是类模版,类模版的本质是写给编译器用的,以实现泛型编程。

 函数传对象,模版传类型,后者是在编译的时候传的,编译器会根据你传入的类型通过模版自动生成一个相应的vector

                                         

vector的数组是所有类型的数组。

对于string和vector<char>的区别,前者是基于“串”而存在的概念,后者是基于“单个字符”而存在的概念。所以vector没有append和+=的概念。

string是专门针对char的数组设计的,vector是针对所有类型的数组设计的。

      无参构造和拷贝构造是重点。也可以通过中括号里加参数给vector赋值。也就是:

vector<char>{'a','b'};

对于第一个无参构造,第一个参数(value_type)类型对应底层是一个什么类型的数组,第二个参数(allocator_type)有缺省值,allocator是空间配置器,也就是内存池,通过该空间配置器会给vector开空间。

对于第二个赋值构造,我们也可以使用如下:

             

                                              (最后两排是其他用法)

对于参数的缺省值value_type()和allocator_type(),就像int()一样,表示创建一个匿名对象。

在C++中有默认的构造函数的,int()就是0,char()就是\0,而如果是自定义类型就会调用默认构造。

    


2.2 遍历vector

如何遍历?正如上文,vector不仅支持基于迭代器的范围for,还可以下标访问。

vector支持下标访问:

          

           


访问方法2:

迭代器:

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

虽然vector还是更多喜欢下标访问,但是迭代器可以便于实现范围for和提高接口的通用性。


2.3 push_back和pop_back的使用

我们以一个string为元素的vector来举例(类似于一个二维char数组)

string类型的vector就可以用到匿名对象(第二个push_back)来便于创建:             ​​​

也可以直接传常量字符串来构造:

                             

我们简单来看下push_back的参数。因为对于push_back:

                   

push_back的参数必须是const string& s,因为涉及传常量字符串和单参数构造函数隐式类型转换,需要改小push_back处参数的权限。

   当string作为vector的元素时,就可以对vector的元素进行+=  ,  因为strng是可以+=的。       

pop_back:

     


2.4对于需要深拷贝的传值优化

不过此时遍历的范围for写的有缺陷,因为e是传值传参,所以每个string都需要深拷贝。但是如果底层的拷贝用的是写时拷贝,在效率方面就优化了太多。

但是当我们不知道底层是不是写时拷贝时,就可以用以下的传引用方法,来降低拷贝的成本。                              

for (const auto& e : v1) {
	cout << e << " ";
}

2.5 insert和erase等

在vector中,insert和erase都没有下标版本,只有迭代器版本:

可发现不能传位置了。

而应该写成 :

             

 

再来观察一下两种insert的用法:

另一种则可以控制多少个数据需要被修改成最后的参数:

emplace和insert的作用是几乎一样的,但是效率有点小差距。


2.6 resize

resize不会改变原有空间的数据,而是在多开出的空间输入你的参数。相当于在数组末尾insert。

 

vector的resize不像string那样默认加\0,而是加0:


2.7 sort的使用

        sort是一个函数模版,参数为迭代器。

                       

可以通过v1.begin()+-n来控制从哪开始,或者利用size来只排序前一半:

                  

默认排序是升序,如果希望降序:

sort的第三个参数表示需要传一个可比较的对象(就像qsort需要传一个函数指针一样)

使用仿函数,仿函数是一个对象

greater是在库中实现的,可以选出更大的,相应的还有less:

可以用greater或less比较两个数,输出为0或1。 

                                  

或者也可以利用匿名对象:

                    

     仿函数的具体内容会在后文中讲解,现在知道有这个东西就行了。


3.练习使用vector

136. 只出现一次的数字 - 力扣(LeetCode)

从题目中也可以看出,C++一般都是传vector,而C语言是传int* 和为了能修改而不得不传指针的returnsize:

                       

思路非常简单并且做过无数遍,按位异或即可。

int singleNumber(vector<int>& nums) {
        int ans=0;
        for(auto e:nums){
            ans^=e;
        }
        return ans;
    }

   杨辉三角118. 杨辉三角 - 力扣(LeetCode)

重点理解:resize / operator[]以及vector的包含。

   类似于一个二维数组

将vector<int>作为参数形成一个新的vector。

所以这里会实例化两个类,一个是vector<int>,另一个是vector<vector<int>>,而在杨辉三角中,每一个vector<int>的大小和元素都是不一样,如下图:

      

通过vector实现了动态二维数组,该数组可以直接由运算符重载而直接用两个方括号访问:

                                        

                                  

杨辉三角的解题思路对于现在的大家应该很简单了:

                 

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
           vector<vector<int>> v;
           v.resize(numRows);
           for(int i =0;i<numRows;++i){
            v[i].resize(i+1,0);
            v[i][0]=v[i][i]=1;
           }
           for(int i=0;i<numRows;++i){
               for(int j=0;j<=i;++j){
                if(v[i][j]==0){
                    v[i][j]= v[i-1][j]+ v[i-1][j-1];
                }
               }
           }
           return v;
    }
};

Leetcode传一维数组时需要一个returnsize,为了能改变其值所以传进来的是int* returnsize(正如第一题)

传二维数组时还需要一个数组returncolumnsize来记录每一个一维数组有多少个元素,为了能改变这个一维数组的值只能传int** returncolumnsize.

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

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

相关文章

老生常谈!程序员为什么要阅读源代码?

大家好&#xff0c;我是码农先森。 阅读源码这是一个老生常谈的话题了&#xff0c;但又是很多人想做又没有付出行动的事情。前段时间我研究了 Swoole 的源代码&#xff0c;并且输出了系列的源码分析文章「感兴趣的朋友可以翻阅以前的文章」。虽然这个过程很枯燥和艰难&#xf…

css font-family

知乎的font-family的设置理解 -apple-system, BlinkMacSystemFont 这两个值是为了确保在macOS和iOS系统上能够使用系统默认字体进行文本渲染。-apple-system特别为Safari浏览器设计&#xff0c;而BlinkMacSystemFont则主要针对基于Chromium的浏览器&#xff08;如Chrome&#…

【Linux】shell——条件判断test,各种运算符,expr

条件判断——test 真——0 假——1 test expression or [ expression ] 整数运算符 字符串运算符 -z 长度是否为0 -n 长度是否不为0 str1 str2 str1 ! str2 补 &&-->逻辑与&#xff0c;前面为真后面才会执行 || -->逻辑或&#xff0c;前面为假后面才…

京东网页html+css简单制作1(附带源码和素材)

一.代码效果展示 代码html骨架结构分为头部top,颈部banner&#xff0c;中间部分main,腿部fortet-image,尾部fortter&#xff0c;五部分组成&#xff0c;从上至下&#xff0c;从左到右结构。&#xff08;总体因为没设计版心&#xff0c;所以位置比较乱&#xff09; 其中中部mai…

云动态摘要 2024-06-11

给您带来云厂商的最新动态,最新产品资讯和最新优惠更新。 最新优惠与活动 [低至1折]腾讯混元大模型产品特惠 腾讯云 2024-06-06 腾讯混元大模型产品特惠,新用户1折起! 云服务器ECS试用产品续用 阿里云 2024-04-14 云服务器ECS试用产品续用 最新产品更新 云服务器运维监…

设计模式-代理模式(结构型)

代理模式 代理模式是一种结构型模式&#xff0c;它可以通过一个类代理另一个类的功能。代理类持有被代理类的引用地址&#xff0c;负责将请求转发给代理类&#xff0c;并且可以在转发前后做一些处理 图解 角色 抽象主题&#xff08;Subject&#xff09;: 定义代理对象和被代理…

【安卓13 源码】Input子系统(2) - input系统与应用进程通信

点击手机屏幕&#xff0c;可以分发input 事件到对应的view&#xff0c;由上一节知道input 是运行在system 进程的&#xff0c;那应用进程与系统进程是如何通讯的呢&#xff0c;相信本文可以给到一点小小的答案。 先给个结论&#xff1a;应用在resume 的时候才去建立与input 服…

项目部署(前后端)

一&#xff1a;多环境概念&#xff1a; 借鉴来源&#xff1a;多环境设计_程序员鱼皮-多环境设计-CSDN博客 为什么需要多环境&#xff1a; 第一个例子&#xff1a;我们可以设想&#xff0c;我们肯定玩过王者荣耀&#xff0c;且王者荣耀也一直在不断更新&#xff0c;如果按我们…

cleanmymac清理时要一直输入密码 CleanMyMac X一直提示输入密码的解决方案

CleanMyMac X是一款专业的Mac清理软件&#xff0c;可智能清理mac磁盘垃圾和多余语言安装包&#xff0c;快速释放电脑内存&#xff0c;轻松管理和升级Mac上的应用。同时CleanMyMac X可以强力卸载恶意软件&#xff0c;修复系统漏洞&#xff0c;一键扫描和优化Mac系统。 在使用Cle…

【人工智能基础学习】Andrew Ng-机器学习基础笔记

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三连支…

HyperSnap软件最新版下载-HyperSnap官方最新版附加详细安装步骤

​HyperSnap是一个老牌优秀的屏幕截图工具&#xff0c;全新界面&#xff0c;不仅能抓取标准桌面程序&#xff0c;还能抓取 DirectX, 3Dfx Glide的 游戏视频或 DVD 屏幕图&#xff0c;能以 20 多种图形格式&#xff08;包括&#xff1a;BMP, GIF,JPEG, TIFF, PCX等&#xff09;保…

鸿蒙开发:应用组件跨设备交互(流转)【跨端迁移】

跨端迁移 概述 在用户使用设备的过程中&#xff0c;当使用情境发生变化时&#xff08;例如从室内走到户外或者周围有更适合的设备等&#xff09;&#xff0c;之前使用的设备可能已经不适合继续当前的任务&#xff0c;此时&#xff0c;用户可以选择新的设备来继续当前的任务&a…

C盘爆满?教你轻松清理无故产生的大量临时文件!

在电脑操作中&#xff0c;用户发现自己系统C盘爆满了&#xff0c;无缘无故产生了大量的临时文件&#xff0c;导致电脑运作变得卡顿&#xff0c;但不知道要怎么操作才能解决这个问题&#xff1f;接下来小编给小伙伴们带来不同的解决方法&#xff0c;轻松清理电脑上的临时文件。 …

【lesson7】服务端业务处理模块实现

文章目录 业务处理实现思路业务处理类设计成员变量成员函数RunModuleupLoadlistShowdownLoadgetETagInfo 业务处理实现思路 云备份项目中 &#xff0c;业务处理模块是针对客户端的业务请求进行处理&#xff0c;并最终给与响应。而整个过程中包含以下要实现的功能&#xff1a; …

这所大学25考研计算机学院专业课已全面改考为408!南京信息工程大学计算机考研!

南京信息工程大学&#xff08;Nanjing University of Information Science and Technology&#xff09;&#xff0c;简称“南信大”&#xff0c;位于江苏省南京市&#xff0c;是一所以大气科学为特色的全国重点大学&#xff0c;由江苏省人民政府、中华人民共和国教育部、中国气…

【lesson1】第三方库(jsoncpp,bundle, httplib)的介绍和使用

文章目录 jsoncpp库json 认识jsoncpp 认识jsoncpp 实现序列化jsoncpp 实现反序列化 bundle库bundle库实现文件压缩bundle库实现文件解压缩 httplib 库httplib 库搭建简单服务器httplib库搭建简单客户端 jsoncpp库 json 认识 json 是一种数据交换格式&#xff0c;采用完全独立…

OS进程取样器OS Process Sampler执行CMD/Shell命令

Apache JMeter - Users Manual: Component Reference 1.背景 项目上最近需要测试一种很少用到的DICOM协议,但是网上资料很少,基本上可以总结为三种方案: 直接发送TCP 16进制数据包,但是参数化数据准备难度大通过开发封装jar包发送,需要开发组提供通过发送cmd命令给前置机…

ES升级--05--快照生成 和备份

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 备份ES数据1.关闭集群自动均衡2.执行同步刷新3.停止集群节点的Elasticsearch服务4.修改Elasticsearch配置文件&#xff0c;开启快照功能&#xff0c;配置仓库目录为…

java:FeignClient通过RequestInterceptor自动添加header

示例代码 【pom.xml】 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>2.3.12.RELEASE</version> </dependency> <dependency><groupId>o…

f-stack和DPDK

GPT-4 (OpenAI) f-stack和DPDK&#xff08;数据平面开发套件&#xff09;都是与高性能网络处理相关的技术。它们的目的是提高数据包的处理速度&#xff0c;优化网络I/O的性能。以下是对这两者的简要解释&#xff1a; 1. **DPDK (Data Plane Development Kit):** DPDK 是一个…