C++初阶:容器(Containers)vector常用接口详解

介绍完了string类的相关内容后:C++初阶:适合新手的手撕string类(模拟实现string类)
接下来进入新的篇章,容器vector介绍:


文章目录

  • 1.vector的初步介绍
  • 2.vector的定义(constructor)
  • 3.vector迭代器( iterator )
  • 4.vector的三种遍历
    • 4.1正常for循环
    • 4.2范围for循环
    • 4.3两种迭代器(正向和反向)
  • 5.vector扩容相关(resize和reserve)
    • 5.2reserve()
    • 5.2resize()
  • 6. vector 增删查改
    • 6.1push_back和pop_back
    • 6.2find、Insert、erase
    • 6.3swap


1.vector的初步介绍

请添加图片描述

翻译过来就是:

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

2.vector的定义(constructor)

请添加图片描述

  1. 默认构造函数:explicit vector (const allocator_type& alloc = allocator_type())。这是默认构造函数,它创建一个空的 std::vector 对象。如果提供了分配器(allocator),则使用提供的分配器;否则使用默认分配器。
  2. 填充构造函数:explicit vector (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type())。这个构造函数创建一个包含==n 个元素的 std::vector,每个元素的值都是 val ==。同样地,您可以选择提供一个分配器,如果没有提供,则使用默认分配器。
  3. 范围构造函数:template <class InputIterator> vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type())。这个构造函数使用迭代器范围[first, last) 中的元素来初始化 std::vector。这使得您可以使用另一个容器的一部分或全部元素来初始化 std::vector
  4. 复制构造函数:vector (const vector& x)。这个构造函数创建一个新的 std::vector,并使用另一个 std::vector x 中的元素进行初始化
构造函数声明接口说明
vector()(重点)无参构造
vector(size_type n, const value_type& val = value_type())构造并初始化n个val
vector(const vector& x)(重点)拷贝构造
vector(InputIterator first, InputIterator last)使用迭代器进行初始化构造
int main()
{vector<int> v1;//空参构造vector<int> v2(5, 1);//构造并初始化5个1vector<int> v3(v2);//拷贝构造string s1("abc");vector<int> v4(s1.begin(), s1.end());//使用迭代器进行初始化构造return 0;
}

请添加图片描述

这里v4中都存的是ASCII码值


3.vector迭代器( iterator )

请添加图片描述

迭代器说明
begin获取第一个数据位置的iterator/const_iterator
end获取最后一个数据的下一个位置的iterator/const_iterator
rbegin获取最后一个数据位置的reverse_iterator (反向迭代器的移动方向是与正向迭代器相反的,即 ++ 操作符会使迭代器向前移动,而 -- 操作符会使迭代器向后移动)
rend获取第一个数据前一个位置的reverse_iterator

4.vector的三种遍历

4.1正常for循环

void test2()
{string s1("abc");vector<char> v(s1.begin(), s1.end());//使用迭代器进行初始化构造for (size_t i = 0; i < v.size(); i++){cout << v[i] << " ";}
}int main()
{test2();
}

请添加图片描述

4.2范围for循环

void test3()
{string s1("abc");vector<int> v(s1.begin(), s1.end());//这里用int,不是charfor (auto e : v){cout << e << " ";}
}int main()
{test3();
}

请添加图片描述

4.3两种迭代器(正向和反向)

void test4()
{string s1("abc");vector<char> v(s1.begin(), s1.end());//使用迭代器进行初始化构造vector<char>::iterator it = v.begin();//正向遍历while (it != v.end()){cout << *it << " ";it++;}cout << endl;vector<char>::reverse_iterator rit = v.rbegin();//反向遍历while (rit != v.rend()){cout << *rit << " ";rit++;//是++不是--}//反向迭代器的移动方向是与正向迭代器相反的//即 ++ 操作符会使迭代器向前移动,而 -- 操作符会使迭代器向后移动
}int main()
{test4();
}

请添加图片描述


5.vector扩容相关(resize和reserve)

接口说明
size获取数据个数
capacity获取容量大小
empty判断是否为空
resize改变vector的size
reserve改变vector的capacity
  • capacity的代码在vs和g++下分别运行会发现,vs下capacity是按1.5倍增长的,g++是按2倍增长的。不要固化的认为,vector增容都是2倍,具体增长多少是根据具体的需求定义的。vs是PJ版本STL,g++是SGI版本STL。
  • reserve只负责开辟空间,如果确定知道需要用多少空间,reserve可以缓解vector增容的代价缺陷问题。
  • resize在开空间的同时还会进行初始化,影响size

5.2reserve()

请添加图片描述

reserve 函数用于改变容器的容量,即修改容器内部用于存储元素的空间大小。这个函数可以用来避免多次重新分配内存的开销,从而提高性能。但需要注意的是,reserve 只会增加容器的容量,而不会影响容器的大小

void test5()
{vector<int> v(10, 1);//10个1cout << v.capacity() << endl;v.reserve(20);cout << v.capacity() << endl;v.reserve(15);cout << v.capacity() << endl;v.reserve(5);cout << v.capacity() << endl;
}int main()
{test5();
}

请添加图片描述

5.2resize()

请添加图片描述

resize 函数用于改变容器的大小,即修改容器中元素的数量。如果将 resize 函数的参数设置为比当前大小小的值,那么容器将缩小到指定的大小,并丢弃多余的元素。如果将参数设置为比当前大小大的值,那么容器将增大到指定的大小,并且新元素不指明的话将被默认构造(对于内置类型,新元素将被初始化为 0)

void test6()
{vector<int> v(10, 1);//10个1cout << "capacity:" << v.capacity() << "size:" << v.size() << endl;v.resize(20);cout << "capacity:" << v.capacity() << "size:" << v.size() << endl;v.resize(15);cout << "capacity:" << v.capacity() << "size:" << v.size() << endl;v.resize(5);cout << "capacity:" << v.capacity() << "size:" << v.size() << endl;
}int main()
{test6();
}

请添加图片描述


6. vector 增删查改

接口说明
push_back尾部插入元素
pop_back尾部删除元素
find查找元素
insert在指定位置插入元素
erase删除指定位置的元素
swap交换两个 vector 的数据空间
operator[]像数组一样使用下标访问元素

6.1push_back和pop_back

请添加图片描述

void test7()
{vector<int> v(10, 1);//10个1for (auto e : v){cout << e << " ";}cout << endl;v.push_back(10);for (auto e : v){cout << e << " ";}cout << endl;v.pop_back();for (auto e : v){cout << e << " ";}cout << endl;
}int main()
{test7();
}

请添加图片描述

6.2find、Insert、erase

  1. find
    • 形式:iterator find (iterator first, iterator last, const T& val);
    • 参数说明:firstlast 表示查找范围的起始和结束迭代器;val 是要查找的值
    • 作用:在指定范围内查找指定的值,并返回第一个匹配元素的迭代器
  2. insert
    • 形式:iterator insert (iterator position, const T& val);
    • 参数说明:position 表示插入位置的迭代器;val 是要插入的值
    • 作用:在指定位置之前插入一个元素
  3. erase
    • 形式:iterator erase (iterator position);iterator erase (iterator first, iterator last);
    • 参数说明:position 表示要删除的位置的迭代器;firstlast 表示要删除的范围的起始和结束迭代器
    • 作用:删除指定位置的元素,或者指定范围内的元素
void test8()
{vector<int> v;for (int i = 1; i < 6; i++){v.push_back(i);}for (auto e : v){cout << e << " ";}cout << endl;vector<int>::iterator it = find(v.begin(), v.end(), 3);//找到3的位置v.insert(it, 0);//插入for (auto e : v){cout << e << " ";}cout << endl;v.erase(v.begin(),v.end());//全删了for (auto e : v){cout << e << " ";}cout << endl;
}int main()
{test8();
}

请添加图片描述

6.3swap

swap

  • 形式:void swap (vector& x);
  • 参数说明:x 是另一个 vector
  • 作用:交换两个 vector 的数据空间,使它们的内容互相交换
void test9()
{vector<int> v1;for (int i = 1; i < 6; i++){v1.push_back(i);}vector<int> v2(10, 1);cout << "还没交换" << endl;for (auto e : v1){cout << e << " ";}cout << endl;v1.swap(v2);//二者交换cout << "交换后" << endl;for (auto e : v1){cout << e << " ";}cout << endl;
}int main()
{test9();
}

请添加图片描述


常用的接口就这些了,下次就来进行模拟实现了,感谢大家支持!!!

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

二进制安全虚拟机Protostar靶场(8)heap3 Fastbins unlink exploit

前言 这是一个系列文章&#xff0c;之前已经介绍过一些二进制安全的基础知识&#xff0c;这里就不过多重复提及&#xff0c;不熟悉的同学可以去看看我之前写的文章 heap3 程序静态分析 https://exploit.education/protostar/heap-three/#include <stdlib.h> #include …

【Unity】重力场中的路径预测方法

前言 笔者前些天参加完了一场72小时的GameJam游戏开发比赛。这次比赛的主题是“探索”&#xff0c;笔者做了一个名为《探索者号》的探索宇宙的游戏&#xff08;游戏名一开始叫做《星际拾荒者》&#xff0c;但这不重要&#xff09;。 在开发过程中&#xff0c;笔者遇到了一些问…

高可用 k8s 1.29 一键安装脚本, 丝滑至极

博客原文 文章目录 集群配置配置清单集群规划集群网络规划 环境初始化主机配置 配置高可用ApiServer安装 nginx安装 Keepalived 安装脚本需要魔法的脚本不需要魔法的脚本配置自动补全加入其余节点 验证集群 集群配置 配置清单 OS&#xff1a; ubuntu 20.04kubernetes&#xf…

(每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第10章 项目进度管理(三)

博主2023年11月通过了信息系统项目管理的考试&#xff0c;考试过程中发现考试的内容全部是教材中的内容&#xff0c;非常符合我学习的思路&#xff0c;因此博主想通过该平台把自己学习过程中的经验和教材博主认为重要的知识点分享给大家&#xff0c;希望更多的人能够通过考试&a…

流量嗅探详解

不少人存在这样的观点&#xff1a;只要计算机安装各种专业的安全软件&#xff0c;系统及时更 新补丁&#xff0c;密码尽可能复杂&#xff0c;那么计算机就会避免遭到入侵。当然这样的确不容易 被入侵&#xff0c;但那也只是针对传统的病毒、木马而言&#xff0c;在流量攻击面前…

汇编笔记 01

小蒟蒻的汇编自学笔记&#xff0c;如有错误&#xff0c;望不吝赐教 文章目录 笔记编辑器&#xff0c;启动&#xff01;debug功能CS & IPmovaddsub汇编语言寄存器的英文全称中英对照表muldivandor 笔记 编辑器&#xff0c;启动&#xff01; 进入 debug 模式 debug功能 …

在C++的union中使用std::string(非POD对象)的陷阱

struct和union的对比 union最开始是C语言中的关键字&#xff0c;在嵌入式中比较常见&#xff0c;由于嵌入式内存比较稀缺&#xff0c;所以常用union用来节约空间&#xff0c;在其他需要节省内存的地方也可以用到这个关键字&#xff0c;写一个简单程序来说明union的用途 struc…

如何合理规划 PostgreSQL 的数据库用户

PostgreSQL 作为世界上最领先的开源数据库&#xff0c;有一套强大的用户角色权限系统&#xff0c;和 MySQL 做一个对比&#xff1a; 但硬币的另一面则是对于简单场景来说增加了复杂度。在许多单应用场景&#xff0c;其实也不需要额外的 schema 层&#xff0c;也不需要额外的 ow…

2 月 7 日算法练习- 数据结构-树状数组上二分

问题引入 给出三种操作&#xff0c; 0在容器中插入一个数。 1在容器中删除一个数。 2求出容器中大于a的第k大元素。 树状数组的特点就是对点更新&#xff0c;成段求和&#xff0c;而且常数非常小。原始的树状数组只有两种操作&#xff0c;在某点插入一个数和求1到i的所有数的…

Sublime Text 3配置 Node.js 开发环境

《开发工具系列》 Sublime Text 3配置 Node.js 开发环境 一、引言二、主要内容2.1 初识 Sublime Text 32.2 初识 Node.js2.3 接入 Node.js2.3.1 下载并安装 Node.js2.3.2 环境变量配置 2.4 配置 Node.js 开发环境2.5 编写 Node.js 代码2.6 运行 Node.js 代码 三、总结 一、引言…

Spring Boot3整合Redis

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 前置条件 1.导依赖 2.配置连接信息以及连接池参数 3.配置序列化方式 4.编写测试 前置条件 已经初始化好一个spr…

C++,stl,deque容器详解

目录 1.deque容器的构造函数 代码示例&#xff1a; 2.deque的赋值操作 3.deque的大小操作 4.deque的插入和删除 5.deque的数据存取 6.deque的排序操作 1.deque容器的构造函数 代码示例&#xff1a; #include<bits/stdc.h> using namespace std;void print(deque…

Spring Cloud使用ZooKeeper作为注册中心的示例

简单的Spring Cloud应用程序使用ZooKeeper作为注册中心的示例&#xff1a; 1.新建模块&#xff1a; 2.勾选依赖&#xff1a; 3.在pom.xml文件中做出部分修改及添加Spring Cloud Zookeeper 依赖版本&#xff1a; 完整pom文件 <?xml version"1.0" encoding&q…

单片机学习笔记---LED点阵屏的工作原理

目录 LED点阵屏分类 LED点阵屏显示原理 74HC595的介绍 一片74HC595的工作原理 多片级联工作原理 总结 LED点阵屏由若干个独立的LED组成&#xff0c;LED以矩阵的形式排列&#xff0c;以灯珠亮灭来显示文字、图片、视频等。LED点阵屏广泛应用于各种公共场合&#xff0c;如汽…

微信小程序(三十八)滚动容器

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.滚动触底事件 2.下拉刷新事件 源码&#xff1a; index.wxml <view class"Area"> <!-- scroll-y 垂直滚动refresher-enabled 允许刷新bindrefresherrefresh 绑定刷新作用函数bindscrollto…

Netty中使用编解码器框架

目录 什么是编解码器&#xff1f; 解码器 将字节解码为消息 将一种消息类型解码为另一种 TooLongFrameException 编码器 将消息编码为字节 将消息编码为消息 编解码器类 通过http协议实现SSL/TLS和Web服务 什么是编解码器&#xff1f; 每个网络应用程序都必须定义如何…

imgaug数据增强神器:增强器一览

官网&#xff1a;imgaug — imgaug 0.4.0 documentationhttps://imgaug.readthedocs.io/en/latest/ github:GitHub - aleju/imgaug: Image augmentation for machine learning experiments. imgaug数据增强神器&#xff1a;增强器一览_iaa 图像增强改变颜色-CSDN博客文章浏览阅…

C++新版本特性

目录: 前言 C11的常用新特性 auto类型推导&#xff1a; auto的限制&#xff1a; auto的应用&#xff1a; decltype类型推导&#xff1a; decltype的实际应用&#xff1a; 使用using 定义别名&#xff1a; 支持函数模板的默认模板参数 : tuple元组&#xff1a; 列表初…

泛型相关内容

1. 什么是泛型 泛型就是定义一种模板&#xff0c;既实现了编写一次&#xff0c;万能匹配&#xff0c;又通过编译器保证了类型安全。 2. 使用泛型 1&#xff09;使用泛型时&#xff0c;把泛型参数<T>替换为需要的class类型&#xff0c;不指定时默认为Obje…

uniapp中配置开发环境和生产环境

uniapp在开发的时候&#xff0c;可以配置多种环境&#xff0c;用于自动切换IP地址&#xff0c;用HBuilder X直接运行的就是开发环境&#xff0c;用HBuilder X发布出来的&#xff0c;就是生产环境。 1.使用HBuilder X创建原生的uniapp程序 选择vue3 2.什么都不改&#xff0c;就…