C++---vector容器

news2024/11/24 14:24:49

是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.coloradmin.cn/o/1591657.html

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

相关文章

算数逻辑单元

目录 一、王道考研ppt总结 二、个人理解 一、王道考研ppt总结 二、个人理解 74181是一款经典的ALU 可以进行加减乘除和与或非、异或等计算&#xff1b;还有移位和求补等 输入有一个CU信号&#xff0c;即控制单元信号&#xff0c;有一个M信号&#xff0c;当M为1时&#xff0c;进…

VBOX ubuntu20.04 安装好后无法启动 terminal 是什么原因?

这种情况通常是 字符问题 先点开 Settings ----> Region & Language , 如下 把系统的语言和地区设置成一致的 再参考这里 https://blog.csdn.net/u010092716/article/details/130968032 再参考这里 https://blog.csdn.net/pxy7896/article/details/135216651 然后重…

记录Ubuntu 20.04中被困扰半年多之久的疑难的解决

一、我的ubuntu20.04症状描述&#xff1a; 在编辑文字文档的过程中&#xff0c;会不定时的出现鼠标指针随意跳动的情形&#xff0c;严重干扰了做文字编辑、编写代码等工作的进行。先后排除了戴尔笔记本及配件故障、鼠标故障、ubuntu系统中文档编辑软件的故障等可能。 二、原来…

初识ansible服务及ansible主机清单配置

目录 1、什么是自动化批量管理 2、自动化工具ansible架构 3、ansible服务专用术语对照表 4、设置主机清单&#xff08;inventory&#xff09; 3.1实验环境准备 3.2配置主机清单 3.2.1分组基本格式 3.2.2指定用户名&#xff0c;密码。端口 3.2.3子组 3.3查看 3.3.1看…

数据同步工具datax配置与示例

文章目录 前言一、部署步骤1、jdk环境2、python环境步骤一&#xff1a;安装方式一&#xff1a;官网下载安装包方式二&#xff1a;brew命令安装 步骤二&#xff1a;配置环境变量步骤三&#xff1a;验证 3、maven环境&#xff08;可选&#xff09; 二、下载安装datax1、下载datax…

LeetCode 二十一:合并两个有序链表 【python】

作者介绍&#xff1a;10年大厂数据\经营分析经验&#xff0c;现任大厂数据部门负责人。 会一些的技术&#xff1a;数据分析、算法、SQL、大数据相关、python 欢迎加入社区&#xff1a;码上找工作http://t.csdnimg.cn/Q59WX作者专栏每日更新&#xff1a; LeetCode解锁1000题: 打…

rabbitmq安装rabbitmq-delayed-message-exchange插件

下载地址&#xff1a;Community Plugins | RabbitMQ 上传到rabbitmq安装目录的/plugins目录下 我的是/usr/lcoal/rabbitmq/plugins/ 直接安装 [rootk8s-node1 rabbitmq]# rabbitmq-plugins enable rabbitmq_delayed_message_exchange [rootk8s-node1 rabbitmq]# rabbitmq-pl…

基于matlab动态化绘制一个彩色边框的爱心

一、版本1 % 定义爱心曲线的参数方程 t linspace(0, 2*pi, 100); x 16*sin(t).^3; y 13*cos(t) - 5*cos(2*t) - 2*cos(3*t) - cos(4*t);% 创建图形 figure; axis equal; axis off; title(爱心);% 循环遍历每个点&#xff0c;绘制不同颜色的线段 for i 1:length(t)-1% 清除…

Linux 内核学习(1) --- 时钟子系统

标题 时钟系统说明时钟树Clock Provider时钟通用数据结构clock_device 的注册clock_provider DTS配置和注册clock consumer时钟系统总结 时钟系统说明 时钟就是 SoC 中的脉搏&#xff0c;由它来控制各个部件按各自的节奏跳动。比如&#xff0c;CPU主频设置&#xff0c;串口的波…

解锁智能未来:用Ollama开启你的本地AI之旅

Ollama是一个用于在本地运行大型语言模型&#xff08;LLM&#xff09;的开源框架。它旨在简化在Docker容器中部署LLM的过程&#xff0c;使得管理和运行这些模型变得更加容易。Ollama提供了类似OpenAI的API接口和聊天界面&#xff0c;可以非常方便地部署最新版本的GPT模型并通过…

Linux 硬链接和软链接怎么区分使用?

一、什么是硬链接和软链接 硬链接 在Linux操作系统中&#xff0c;硬链接相当于存储在硬盘驱动器中的文件&#xff0c;它实际上引用或指向硬盘驱动器上的某个点。硬链接是原始文件的镜像副本。 硬链接与软链接的区别在于&#xff0c;删除原始文件不会影响硬链接&#xff0c;但…

研发岗-面临统信UOS系统配置总结

第一步 获取root权限 配置环境等都需要用到root权限&#xff0c;所以我们先获取到root权限&#xff0c;方便下面的操作 下载软件 在UOS应用商店下载的所需应用 版本都比较低 安装node 官网下载了【arm64】的包&#xff0c;解压到指定文件夹&#xff0c;设置链接&#xff0…

在Windows下面的vscode配置cmake使用vcpkg包管理器

安装 vscode下载地址 cmake下载地址 vcpkg下载地址 创建CMake项目 // main.cpp #include <fmt/core.h>int main() {fmt::print("Hello World!\n");return 0; }// CMakeLists.txtcmake_minimum_required(VERSION 3.10)project(HelloWorld)find_package(fmt…

数据结构基础 ——栈和队列(三)

一、物理结构和逻辑结构 物理结构就是看得见&#xff0c;摸得着。而数组和链表&#xff0c;就是内存中实实在在的存储结构。逻辑结构就是看不见、摸不着。 二、 栈(stack&#xff09; 栈(stack&#xff09;是一种线性数据结构&#xff0c;栈中的元素只能先进后出 (First In La…

GitHub repository - Watch - Star - Fork - Follow

GitHub repository - Watch - Star - Fork - Follow References 眼睛图标旁边写着 Watch 字样。点击这个按钮就可以 Watch 该仓库&#xff0c;今后该仓库的更新信息会显示在用户的公开活动中。Star 旁边的数字表示给这个仓库添加 Star 的人数。这个数越高&#xff0c;代表该仓库…

【Java】第十五届蓝桥杯JavaB组第一道填空题

&#xff03;【Java】第十五届蓝桥杯JavaB组第一道填空题 大家好 我是寸铁&#x1f44a; 总结了一篇【Java】第十五届蓝桥杯JavaB组第一道填空题文章 喜欢的小伙伴可以点点关注 &#x1f49d; Java B组 第一道填空题题解如下:

Excel从零基础到高手【办公】

第1课 - 快速制作目录【上篇】第1课 - 快速制作目录【下篇】第2课 - 快速定位到工作表的天涯海角第3课 - 如何最大化显示工作表的界面第4课 - 给你的表格做个瘦身第5课 - 快速定位目标区域所在位置第6课 - 快速批量填充序号第7课 - 按自定义的序列排序第8课 - 快速删除空白行第…

计算机视觉异常检测——PatchCore面向全召回率的工业异常检测

1. 概述 异常检测问题在工业图像数据分析中扮演着至关重要的角色&#xff0c;其目的是从大量正常数据中识别出异常行为或模式。这一任务的挑战在于&#xff0c;正常数据的样本相对容易获取&#xff0c;而异常情况却因其稀有性和多样性而难以收集。为了解决这一问题&#xff0c…

【C++类和对象】上篇

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

MDK平台 - Code, RO-data , RW-data, ZI-data详解

文章目录 1 . 前言2 . Code, RO-data , RW-data, ZI-data解析3 . RAM上电复位4 . 细节扩展5 . 总结 【全文大纲】 : https://blog.csdn.net/Engineer_LU/article/details/135149485 1 . 前言 MDK编译后&#xff0c;会列出Code, RO-data , RW-data, ZI-data&#xff0c;以下解析…