C++---vector容器

是STL容器中的一种常用的容器,由于其大小(size)可变,常用于数组大小不可知的情况下来替代数组。vector容器与数组十分相似,被称为动态数组。时间复杂度为O(1)。

数组数据通常存储在栈中,vector数据通常存储在堆中。

动态扩展不是在原空间后加入空间,而是寻找更大空间,将数据拷贝新空间,释放新空间。

头文件:#include <vector>

迭代器类似于指针,提供了对象的间接访问,但获取迭代器并不是使用取地址符。如果将指针理解为元素的“地址”,那么迭代器可以理解为元素的“位置”。可以使用迭代器访问某个元素,迭代器也能从一个元素移动到另一个元素。

一个迭代器的范围由一对迭代器表示,分别为 begin 和 end。其中 begin 成员返回指向第一个元素的迭代器;end 成员返回容器最后一个元素的下一个位置(one past the end),也就是指向一个根本不存在的尾后位置。

vector初始化

vector<T> v1                    创建一个名为v1是元素类型为T的空vector

vector<int> v2 (n):            创建一个vector,元素类型为int,元素个数为n,值默认为0

vector<int> v3 {1,2,3,4,5}  vector有5个数,注意花括号

vector<int>v4 (4,1)            vector由4个值为1组成

vector<int>v5 (v4)             将v4所有值复制到v5中

vector<int>v6(v3.begin(), v3.end())  将v3的值从头到尾复制到v6

vector<int>v7(v3.rbegin(), v3.rend()) 将v3的值从尾到头复制到v7

cbegin    和begin()功能相同,在其基础上增加了 const 属性,不能用于修改元素。
cend       和end()功能相同,在其基础上增加了 const 属性,不能用于修改元素。
crbegin   和rbegin()功能相同,在其基础上增加了 const 属性,不能用于修改元素。
crend      和rend()功能相同,在其基础上增加了 const 属性,不能用于修改元素。

vector方法

v2.empty() 判断v2是否为空,为空返回true,否则返回false

v2不为空,返回3

if(v2.empty()) {return 2;
}else{return 3;
}

元素长度

v2.size() 返回实际v2中的元素个数

int len = v2.size();

v2.capacity()返回v2中可以容纳的元素个数

区分:capacity 当前vector分配的大小,size 当前使用数据的大小

v2.resize()改变v2中的实际元素个数

v2.reserve()增加v2 的容量

访问元素

operator[] 用于从vector中访问指定元素,它接受一个索引并返回指定位置元素的引用。语法:

 vector::operator[size_type n];

例如:v2[n] 是v2第n个位置元素的引用,不能用于下标操作添加元素,像v2[7]=5是错的。vector容器的下标也是从0开始计数的

vector.at(i)等同于vector[i],访问数组下表的元素,例如:v2.at(2) 返回下标为2的值的元素

两者区别:虽然两者访问元素都不能越界,但是operator不做边界检查,哪怕越界也会返回一个引用(错误的),at会做边界检查,如果越界,会抛出std::out_of_range异常。

cout<<v2[3]<<endl;
cout<<v2.at(3)<<eendl;

v2.front()返回第一个元素

v2.back()返回最后一个元素

v2.data()返回v2第一个元素的指针

元素排序

sort 需要头文件 #include <algorithm>

sort(v2.begin(), v2.end())一种是两个参数,一般为升序(由小到大)

sort(v2.begin(), v2.end(), t),是三个参数,第三个参数可以写排序规则,一般搭配lambda表达式的捕获列表使用

vector<int> a{0,10,9,8,1,5,2,3,6,4,7};
bool cmp(int x,int y){return x>y;}
sort(a.begin(), a.end(),cmp);
//两者等价
sort(a.begin(), a.end(),[](int x, int y){return x > y;});
//原有形式,省略是因为C++可以自动识别函数返回值得数据类型
sort(a.begin(), a.end(),[](int x,int y) -> bool {return x>y;} );

reverse(v2.begin(), v2.end()) 逆序输出

reverse(a.begin(), a.end());  // 原位逆序排列
//结果
7 4 ....9 10 0

unique(v2.begin(), v2.end())将输入序列相邻的重复项“消除”,一般搭配sort使用,先排序后消除。

例如,0 0 0 0 3 5 输出后 0 3 5

交换元素

v2.swap() 交换v2 其中的两个元素的所有内容

swap() 函数在头文件 <algorithm> 和 <utility> 中都有定义,使用时引入其中一个即可。

v2.assign() 用新元素替换所有内容

添加元素

向 vector 容器中添加元素的唯一方式就是使用它的成员函数,如果不调用成员函数,非成员函数既不能添加也不能删除元素。

v3.push_back(v) 在v3尾端添加一个值为v的元素

v3.push_back(5);
cout<<v3<<endl;
//结果 1,2,3,4,5,5

v2.emplace_back()  在尾部添加一个元素

    vector<int> values{};values.emplace_back(1);values.emplace_back(2);for (int i = 0; i < values.size(); i++) {cout << values[i] << " ";}//结果1 2

两者区别在于底层实现的机制不同。push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。

插入元素

v2.insert(pos,elem)在迭代器 pos 指定的位置之前插入一个新元素elem

iterator insert(pos,n,elem)在迭代器 pos 指定的位置之前插入 n 个元素 elem,并返回表示第一个新插入元素位置的迭代器。
iterator insert(pos,first,last) 在迭代器 pos 指定的位置之前,插入其他容器(不仅限于vector)中位于 [first,last) 区域的所有元素,并返回表示第一个新插入元素位置的迭代器。
iterator insert(pos,initlist)在迭代器 pos 指定的位置之前,插入初始化列表(用大括号{}括起来的多个元素,中间有逗号隔开)中所有的元素,并返回表示第一个新插入元素位置的迭代器。

插入有很多种形式

vector<int> demo{1,2};
//第一种格式用法
demo.insert(demo.begin() + 1, 3);//{1,3,2}
//第二种格式用法
demo.insert(demo.end(), 2, 5);//{1,3,2,5,5}
//可以看出end指的不是数组最后一位,而是最后一位的下一个位置
//第三种格式用法
array<int,3>test{ 7,8,9 };
demo.insert(demo.end(), test.begin(), test.end());//{1,3,2,5,5,7,8,9}
//第四种格式用法
demo.insert(demo.end(), { 10,11 });//{1,3,2,5,5,7,8,9,10,11}

v2.emplace()  指定位置前插入一个新元素,emplace() 每次只能插入一个元素,而不是多个。

vector<int> demo1{1,2};
//emplace() 每次只能插入一个 int 类型元素
demo1.emplace(demo1.begin(), 3);
for (int i = 0; i < demo1.size(); i++) {cout << demo1[i] << " ";
}
//结果 3 1 2

emplace与insert比较,emplace效率更高,因为,insert需要将新元素将其生成,再将其拷贝或复制到容器中,emplace是直接在容器指定位置构造元素。

删除元素

v3.pop_back();
//结果 从1 2 3 4 5 5 变为1 2 3 4 5
vector<int>demo{ 1,2,3,4,5 };
auto iter = demo.erase(demo.begin() + 1);//删除元素 2
for (int i = 0; i < demo.size(); i++) {cout << demo[i] << " ";
}
//iter迭代器指向元素 3
cout << endl << *iter << endl;//结果
1 3 4 5
3
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;int main()
{vector<int>demo{ 1,2,3,4,5 };//交换要删除元素和最后一个元素的位置swap(*(std::begin(demo)+1),*(std::end(demo)-1));//等同于 swap(demo[1],demo[4])//交换位置后的demo容器for (int i = 0; i < demo.size(); i++) {cout << demo[i] << " ";}demo.pop_back();cout << endl << "size is :" << demo.size() << endl;cout << "capacity is :" << demo.capacity() << endl;//输出demo 容器中剩余的元素for (int i = 0; i < demo.size(); i++) {cout << demo[i] << " ";}return 0;
}
//结果
1 5 3 4 2
size is :4
capacity is :5
1 5 3 4
vector<int> demo{ 1,2,3,4,5 };
//删除 2、3
auto iter = demo.erase(demo.begin()+1, demo.end() - 2);
for (int i = 0; i < demo.size(); i++) {cout << demo[i] << " ";
}//结果
1 4 5
vector<int>demo{ 1,3,3,4,3,5 };
//交换要删除元素和最后一个元素的位置
auto iter = remove(demo.begin(), demo.end(), 3);
//输出剩余的元素
for (auto first = demo.begin(); first < iter;++first) {cout << *first << " ";
}
//结果
1 4 5
长度仍为6

注意,在对容器执行完 remove() 函数之后,由于该函数并没有改变容器原来的大小和容量,因此无法使用之前的方法遍历容器,而是需要向程序中那样,借助 remove() 返回的迭代器完成正确的遍历。

remove() 的实现原理是,在遍历容器中的元素时,一旦遇到目标元素,就做上标记,然后继续遍历,直到找到一个非目标元素,即用此元素将最先做标记的位置覆盖掉,同时将此非目标元素所在的位置也做上标记,等待找到新的非目标元素将其覆盖。因此,demo为1 3 3 4 3 5,删除3,得到的结果为 1 4 5 4 3 5

过程:3做标记,3再做标记,4覆盖第一个3,做标记,3再做标记,5覆盖第二个3,做标记。

所以,可以使用 erase() 成员函数删掉这些 "无用" 的元素。

    vector<int>demo{ 1,3,3,4,3,5 };//交换要删除元素和最后一个元素的位置auto iter = remove(demo.begin(), demo.end(), 3);demo.erase(iter, demo.end());//输出剩余的元素for (int i = 0; i < demo.size();i++) {cout << demo[i] << " ";}
//结果 1 4 5
长度变为3
    vector<int>demo{ 1,3,3,4,3,5 };//交换要删除元素和最后一个元素的位置demo.clear();cout << "size is :" << demo.size() << endl;cout << "capacity is :" << demo.capacity() << endl;
//结果
size is :0
capacity is :6

二维数组

完整版:vector<vector<int>> table(size1, vector<int>(size2, 0)); 行列都给了

        名为table的vector容器包含元素为vector的容器。列为size2,行为size1,值为0。

省略版:vector<vector<int>> table; 行列未知

               vector<vector<int>> table(5); 行为5,也就是长度

获取二维数组长度

int size_row = table.size();  //获取行数
int size_col = table[0].size();  //获取列数

访问二维数组

for (int i = 0; i < a.size(); i++)
{for (int j = 0; j < a[0].size(); j++)//注意如果arr为空不可直接arr[0]{cout << a[i][j] << endl;}
}

https://blog.csdn.net/aruewds/article/details/117375364

C++ STL vector插入元素(insert()和emplace())详解 (biancheng.net)

http://t.csdnimg.cn/Ej3rl

http://t.csdnimg.cn/ebFXf

使用lambda表达式实现sort的自定义排序 - octal_zhihao - 博客园 (cnblogs.com)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ 二重指针

一 指向指针的指针 如果在一个指针变量中存放的是另一个变量的指针的地址&#xff0c;称该指针为指向指针的指针&#xff0c;即二重指针。

2.1 LeetCode总结(基本算法)_DFS

1.4 练习 104. 二叉树的最大深度 int maxDepth(struct TreeNode *root, int len) {if (root NULL) {return len;}return fmax(maxDepth(root->left, len1), maxDepth(root->right, len1)); }二叉树最大深度就是基本的递归思路的求解&#xff0c; 手法主要是递归下去之…

C语言基础(三)

C语言基础 三大结构顺序结构选择结构单分支选择结构双分支选择结构多分支选择结构if ...else if....elseswitch语句 循坏结构for循环表达式1可以省略吗&#xff1f;表达式2可以省略吗&#xff1f;表达式3可以省略吗&#xff1f;for循坏的嵌套 while循环do while循坏while与do w…

android支付宝接入流程

接入前准备 接入APP支付能力前&#xff0c;开发者需要完成以下前置步骤。 本文档展示了如何从零开始&#xff0c;使用支付宝开放平台服务端 SDK 快速接入App支付产品&#xff0c;完成与支付宝对接的部分。 第一步&#xff1a;创建应用并获取APPID 要在您的应用中接入支付宝…

【新版】系统架构设计师 - 知识点 - 结构化开发方法

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 知识点 - 结构化开发方法结构化开发方法结构化分析结构化设计 数据流图和数据字典模块内聚类型与耦合类型 架构 - 知识点 - 结构化开发方法 结构化开发方法 分析阶段 工具&#xff1a;数据流图、…

前端学习<四>JavaScript基础——20-函数简介

函数的介绍 函数&#xff1a;就是一些功能或语句的封装。在需要的时候&#xff0c;通过调用的形式&#xff0c;执行这些语句。 补充&#xff1a; 函数也是一个对象 使用typeof检查一个函数对象时&#xff0c;会返回 function 函数的作用&#xff1a; 一次定义&#xff0c;…

腾讯云服务器搭建网站教程,新手跟着流程一步步操作

使用腾讯云服务器搭建网站全流程&#xff0c;包括轻量应用服务器和云服务器CVM建站教程&#xff0c;轻量可以使用应用镜像一键建站&#xff0c;云服务器CVM可以通过安装宝塔面板的方式来搭建网站&#xff0c;腾讯云服务器网txyfwq.com整理使用腾讯云服务器建站教程&#xff0c;…

《黑马点评》Redis高并发项目实战笔记(上)P1~P45

P1 Redis企业实战课程介绍 P2 短信登录 导入黑马点评项目 首先在数据库连接下新建一个数据库hmdp&#xff0c;然后右键hmdp下的表&#xff0c;选择运行SQL文件&#xff0c;然后指定运行文件hmdp.sql即可&#xff08;建议MySQL的版本在5.7及以上&#xff09;&#xff1a; 下面这…

Ubuntu20.04安装ROS过程记录以及常见报错处理

官网安装步骤如下&#xff1a; http://wiki.ros.org/cn/noetic/Installation/Ubuntu#A.2BXwBZy1uJiMU- 第一个&#xff1a;添加ROS软件源 sudo sh -c echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-la…

2024年mathorcup数学建模C题思路分析-物流网络分拣中心货量预测及人员排班

# 1 赛题 C 题 物流网络分拣中心货量预测及人员排班 电商物流网络在订单履约中由多个环节组成&#xff0c;图 ’ 是一个简化的物流 网络示意图。其中&#xff0c;分拣中心作为网络的中间环节&#xff0c;需要将包裹按照不同 流向进行分拣并发往下一个场地&#xff0c;最终使包裹…

Quantum Temple借助Sui通过NFT推动再生旅游

从金融到艺术&#xff0c;从游戏到无线网络&#xff0c;各行各业都涌现出大量初创公司&#xff0c;利用区块链技术颠覆现状。说到旅游业&#xff0c;让人联想到拥挤的机场、快节奏的旅游和豪华游轮&#xff0c;可能看起来对区块链创新持守旧态度。一家初创公司认为现在是时候改…

【神经网络与深度学习】循环神经网络基础

tokenization tokenization&#xff1a;分词 每一个词语都是token 分词方法&#xff1a;转为单个词、转为多个词语 N-gram表示法 准备词语特征的方法 &#xff08;把连续的N个词作为特征&#xff09; 如 ”我爱你“——>[我&#xff0c;爱&#xff0c;你] 2-gram——[[我…

MySQL 嵌套查询

嵌套查询 是指在一个完整的查询语句之中&#xff0c;包含若干个不同功能的小查询&#xff1b;从而一起完成复杂查询的一种编写形式。包含的查询放在&#xff08;&#xff09;里 &#xff0c; 包含的查询出现的位置&#xff1a; 位置含义SELECT之后把查询结果作为表头使用FROM…

Redis中的集群(九)

集群 消息 集群中的各个节点通过发送和接收消息(message)来进行通信&#xff0c;我们称发送消息的节点为发送者(sender),接收消息 的节点成为接收者&#xff0c;如图所示。节点发送的消息主要有以下五种: 1.MEET消息:当发送者接到客户端发送的CLUSTER MEET命令时&#xff0c…

LabVIEW电信号傅里叶分解合成实验

LabVIEW电信号傅里叶分解合成实验 电信号的分析与处理在科研和工业领域中起着越来越重要的作用。系统以LabVIEW软件为基础&#xff0c;开发了一个集电信号的傅里叶分解、合成、频率响应及频谱分析功能于一体的虚拟仿真实验系统。系统不仅能够模拟实际电路实验箱的全部功能&…

ExpressLRS硬件实测性能分析

ExpressLRS硬件实测性能分析 1. 源由2. 远航测试3. 实验室测试3.1 芯片RSSI与实测功率差异3.2 SNR信噪比稳定3.3 140db衰减器衰减&#xff0c;40个频点信号稳定 4. 外场测试4.1 无屏蔽样品4.2 有屏蔽样品4.3 有屏蔽vs无屏蔽样品 5. 估算6. 总结7. 补充说明 -- 50mW视频 1. 源由…

降额的秘密——不要挑战datasheet!

原文来自微信公众号&#xff1a;工程师看海&#xff0c;与我联系&#xff1a;chunhou0820 看海原创视频教程&#xff1a;《运放秘籍》 大家好&#xff0c;我是工程师看海。 什么是降额设计&#xff1f;我们为什么要降额&#xff1f; 额指的是额定工作状态&#xff0c;降额就是…

【蓝桥杯】第十五届填空题a.握手问题

题解&#xff1a; 根据问题描述&#xff0c;总共有 50 人参加会议&#xff0c;每个人除了与自己以外的其他所有人握手一次。但有 7 个人彼此之间没有进行握手&#xff0c;而与其他所有人都进行了握手。 首先&#xff0c;计算所有人进行握手的总次数&#xff1a; 总人数为 50 …

Day19-【Java SE进阶】网络编程

一、网络编程 1.概述 可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)。java.net,*包下提供了网络编程的解决方案! 基本的通信架构 基本的通信架构有2种形式:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端)。 网络通信的…

拓展企业发展新天地:低代码开发平台的策略价值

一、什么是低代码开发&#xff1f; 低代码开发平台&#xff1a;一个号称在几分钟内就能构建出一套企业内部适用的系统开发工具。低代码开发平台可以从降低开发者技术门槛、减少企业人力成本、协同共享资源、灵活搭建组件、减少bug率、按需收费等多个方面降低企业开发成本。 曾…