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)
相关文章:
C++---vector容器
是STL容器中的一种常用的容器,由于其大小(size)可变,常用于数组大小不可知的情况下来替代数组。vector容器与数组十分相似,被称为动态数组。时间复杂度为O(1)。 数组数据通常存储在栈中,vector数据通常存储…...
面向电力行业定制安全云工作站解决方案,麒麟信安出席2024年电力企业信创替代技术研讨会
日前,由中国电子企业协会主办的“2024年电力企业信创替代技术研讨会”在江苏南京正式召开。会议以国家推进实现自主可控、加快建设“数字中国”为大背景,聚焦电力企业紧抓“信创替代”机遇,通过安全可靠的软硬件迭代升级,实现企业…...
初识 QT
初始QT 什么是QTQT发展史QT支持的平台QT的优点QT的应用场景搭建QT开发环境QT的开发工具概述QT下载安装 使用QT创建项目QT 实现Hello World程序使用按钮控件来实现使用标签控件来实现 项目文件解析widget.hmain.cppwidget.cppwidget.ui.pro文件 对象树QT 窗口坐标体系 什么是QT …...
4. Django 探究FBV视图
4. 探究FBV视图 视图(Views)是Django的MTV架构模式的V部分, 主要负责处理用户请求和生成相应的响应内容, 然后在页面或其他类型文档中显示. 也可以理解为视图是MVC架构里面的C部分(控制器), 主要处理功能和业务上的逻辑. 我们习惯使用视图函数处理HTTP请求, 即在视图里定义def…...
二手车价格预测第十三名方案总结
代码开源链接:GitHub - wujiekd/Predicting-used-car-prices: 阿里天池与Datawhale联合举办二手车价格预测比赛:优胜奖方案代码总结 比赛介绍 赛题以二手车市场为背景,要求选手预测二手汽车的交易价格,这是一个典型的回归问题。…...
力扣刷题 二叉树层序遍历相关题目II
NO.116 填充每个节点的下一个右侧节点指针 给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下: struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针,…...
智能电网将科技拓展至工厂之外的领域
【摘要/前言】 物联网已然颠覆我们日常生活的许多层面。在家居方面,家电变成连网设备,不仅让我们能控制灯光与上网购物,甚至在出门时提供安全功能。在工业领域,智能工厂改变产品制造的方式。工业物联网(IIoT)不仅让制造商更加敏捷…...
单列模式1.0
单列模式 单例模式能保证某个类在程序中只存在唯⼀⼀份实例, ⽽不会创建出多个实例 1.饿汉模式 只要程序一启动就会立即创建出一个对象 class Signleton{private static Signleton instancenew Signleton();//防止在以后的代码中再创建对象,我们将构造方法private,…...
golang kafka sarama源码分析
一些理论 1.topic支持多分区,每个分区只能被组内的一个消费者消费,一个消费者可能消费多个分区的数据; 2.消费者组重平衡的分区策略,是由消费者自己决定的,具体是从消费者组中选一个作为leader进行分区方案分配&#…...
计算机组成原理【CO】Ch2 数据的表示和应用
文章目录 大纲2.1 数制与编码2.2 运算方法和运算电路2.3 浮点数的表示和运算 【※】带标志加法器OFSFZFCF计算机怎么区分有符号数无符号数? 【※】存储排列和数据类型转换数据类型大小数据类型转换 进位计数制进制转换2的次幂 各种码的基本特性无符号整数的表示和运算带符号整…...
dfs回溯 -- Leetcode46. 全排列
题目链接:46. 全排列 题目描述 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1: 输入:nums [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示…...
设计模式-接口隔离原则
基本介绍 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上先看一张图: 类A通过接口Interface1 依赖类B,类C通过接口Interface1 依赖类D,如果接口Interface1对于类A和类C来说不是最小接口,那么类…...
BD202311夏日漫步(最少步数,BFS或者 Dijstra)
本题链接:码蹄集 题目: 夏日夜晚,小度看着庭院中长长的走廊,萌发出想要在上面散步的欲望,小度注意到月光透过树荫落在地砖上,并且由于树荫的遮蔽度不通,所以月光的亮度不同,为了直…...
React - 你知道props和state之间深层次的区别吗
难度级别:初级及以上 提问概率:60% 如果把React组件看做一个函数的话,props更像是外部传入的参数,而state更像是函数内部定义的变量。那么他们还有哪些更深层次的区别呢,我们来看一下。 首先说props,他是组件外部传入的参数,我们知道…...
mysql 查询实战-变量方式-解答
对mysql 查询实战-变量方式-题目,进行一个解答。(先看题,先做,再看解答) 1、查询表中⾄少连续三次的数字 1,处理思路 要计算连续出现的数字,加个前置变量,记录上一个的值,…...
SpringBoot3配置SpringSecurity6
访问1:localhost:8080/security,返回:需要先认证才能访问(说明没有权限) 访问2:localhost:8080/anonymous,返回:anonymous(说明正常访问) 相关文件如下&…...
Unity之Unity面试题(三)
内容将会持续更新,有错误的地方欢迎指正,谢谢! Unity之Unity面试题(三) TechX 坚持将创新的科技带给世界! 拥有更好的学习体验 —— 不断努力,不断进步,不断探索 TechX —— 心探索、心进取…...
Linux命令-dos2unix命令(将DOS格式文本文件转换成Unix格式)
说明 dos2unix命令 用来将DOS格式的文本文件转换成UNIX格式的(DOS/MAC to UNIX text file format converter)。DOS下的文本文件是以 \r\n 作为断行标志的,表示成十六进制就是0D0A。而Unix下的文本文件是以\n作为断行标志的,表示成…...
企业怎么做数据分析
数据分析在当今信息化时代扮演着至关重要的角色。能够准确地收集、分析和利用数据,对企业的决策和发展都具有重要意义。数聚将介绍企业如何合理地利用数据分析,如何协助企业在竞争激烈的市场中取得优势。 一、建立完善的数据收集系统 在进行数据分析之…...
1111111111
c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话: 知不足而奋进,望远山而前行&am…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
