6.vector、set和map

news2024/12/22 20:22:42

一、vector

1.简介

有些时候想开一个数组,但是却不知道应该开多大长度的数组合适,因为我们需要用到的数组可能会根据情况变动。这时候我们就需要用到动态数组。

所谓动态数组,也就是不定长数组,数组的长度是可以根据我们的需要动态改变的。动态数组的实现也不难,但是在 C + + C++ C++里面有已经写好的标准模板库 S T L STL STL,实现了集合、映射表、栈、队列等数据结构和排序、查找等算法。我们可以很方便地调用标准库来减少我们的代码量。

C + + C++ C++中动态数组写作vector C C C语言中没有标准库,这也是为什么参加比赛推荐用 C + + C++ C++而不用 C C C的原因。

2.定义

#include <vector>
using namespace std;
int main()
{
    return 0;
}

使用 S T L STL STL的动态数组需要首先在代码的开头引入这个头文件,并不要忘记using namespace std;

vector<T> vec;

T T T表示我们所定义的数组存储数据的类型。它可以是int,double这样的基本数据类型,可以是typedef之后的代词,也可以是自定义的结构体类型,甚至可以是其他的 S T L STL STL类型。

typedef long long ll;
vector<int> a;
vector<double> b;
vector<ll> c;
vector<node> d;
vector<vector<ll> >e;

一开始定义好的动态数组的长度为 0 0 0,代表一个空的数组。

3.基本操作

(1)插入元素到尾部push_back()

vector<int> vec; //{}
vec.push_back(1);//{1}
vec.push_back(2);//{1,2}
vec.push_back(3);//{1,2,3}

(2)访问以及修改某一元素的值

cout<<vec[2]<<endl;//3
vec[2]=10;
cout<<vec[2]<<endl;//10

注意动态数组默认的下标是从 0 0 0开始的。除此以外,所有的操作和普通的数组是一样的。

(3)获取数组长度size()

cout<<vec.size()<<endl;//3
for(int i=0;i<vec.size();i++)
    cout<<vec[i]<<endl;
//{1,2,10}

这里的size()也可以用length()代替,它们这个使用条件下完全相同

(4)删除末尾元素

vec.pop_back();//{1,2}
vec.pop_back();//{1}

(5)清空数组

vec.push_back(10);//{1,10}
vec.push_back(20);//{1,10,20}
vec.clear();      //{}

但需要注意的是,clear()只清空了数组,但没有释放掉动态数组的空间

vector<int> x;
{
    vector<int> New;
    x.swap(New);
}

如果要释放掉vector的空间,那么最好的方法是创建一个空的数组,并将其替换。

(6)初始化

int n=10;
vector<int> vec(n,1);

这里给数组预先分配了长度为 n n n的空间,并将这 n n n个元素全部设为初始值 1 1 1

二、set

1.简介

集合是一个特殊的数据结构,在集合中不会出现同样的元素。集合中的元素是按一定的顺序排列的,默认按照从小到大的顺序。我们可以通过迭代器来顺序访问每一个元素。

如果想用可重复的集合,那么可以使用multiset,它们的实现方式都是红黑树,支持的函数也都差不多,这里不再赘述。

2.定义

set<T> s;

T T T表示我们所定义的数组存储数据的类型。它可以是int,double这样的基本数据类型,可以是typedef之后的代词,也可以是自定义的结构体类型,甚至可以是其他的 S T L STL STL类型。

#include <set>
using namespace std;

typedef long long ll;
struct node
{
    ll x,y;
    bool operator < (const node &a) const
    {
        if(x==a.x)
            return y<a.y;
        return x<a.x;
    }
};
set<int> a;
set<double> b;
set<ll> c;
set<node> d;
set<vector<ll> >e;

但需要注意的是,如果定义的集合是建立在结构体上的,因为涉及到set的有序性,所以必须重载运算符。

一开始定义好的集合的长度为 0 0 0,代表一个空的集合。

3.基本操作

(1)插入元素insert()

set<int> s; //{}
s.insert(2);//{2}
s.insert(1);//{1,2}
s.insert(3);//{1,2,3}
s.insert(3);//{1,2,3}
  • set中插入元素时,会自动排序。
  • set中插入已有元素时,插入不会产生任何效果。

(2)查找某一元素count()

由于set是有序的,所以可以很快速的查询出某一个元素是否在集合中。

//{1,2,3}
if(s.count(5))
    cout<<"5 is in the set."<<endl;
else
    cout<<"5 is not in the set."<<endl;

(3)获取集合大小size()

//{1,2,3}
cout<<s.size()<<endl;//3

(4)删除某一个元素

s.erase(10);//{1,2}
s.earse(8);//{1,2}

删除集合中的某一个元素,如果此元素不在集合中,那么删除不会产生任何效果。

(5)查找某一元素find()

//{1,2,10,20}
if(s.find(10)!=s.end())
    cout<<"10 is in the set."<<endl;

find()函数可以查找一个元素并返回其对应的迭代器,如果集合中没有该元素,那么就会返回end()

(6)清空集合clear()

//{1,2}
s.insert(10);//{1,2,10}
s.insert(20);//{1,2,10,20}
s.clear();   //{}

但需要注意的是,与vector不同的是,setclear()不仅删除了元素,还清空了内存。

(7)遍历

//{1,2,10,20}
for(set<int>::iterator it=s.begin();it!=s.end();it++)
{
    cout<<(*it)<<" ";
}
//1 2 10 20

因为集合使用的不是连续空间,而是使用了迭代器,所以我们需要使用迭代器iterator来遍历集合。

注意s.begin()s.end()并不是整数,而是迭代器类型,所以it!=s.end()不能改成it<s.end()

遍历的结果是按照定义的顺序排列的。

三、map

1.简介

两个非空集合A与B间存在着对应关系 f f f,而且对于 A A A中的每一个元素 a a a B B B中总有唯一元素 b b b与它对应,就将这种对应为从A到B的映射,记作 f : A → B f:A\rightarrow B f:AB。其中, b b b称为元素 a a a在映射 f f f下的,记作: b = f ( a ) b=f(a) b=f(a) a a a称为 b b b关于映射 f f f原像。集合 A A A中所有元素的像的集合称为映射 f f f的值域,记作 f ( A ) f(A) f(A)

比如集合{‘A’,‘B’,‘C’}与{1,2,3}可以构成如下映射:

在这里插入图片描述

2.定义

map<T1,T2> mp;

T 1 , T 2 T1,T2 T1,T2表示我们所定义的数组存储数据的类型,它们可以是相同的也可以是不同的。它可以是int,double这样的基本数据类型,可以是typedef之后的代词,也可以是自定义的结构体类型,甚至可以是其他的 S T L STL STL类型。

#include <map>
using namespace std;

typedef long long ll;
map<int,int> a;
map<double,int> b;
map<ll,ll> c;
map<node> d;
map<vector<ll> >e;

一开始定义好的动态数组的长度为 0 0 0,代表一个空的数组。

3.基本操作

(1)插入一对映射insert()

map<string,int> mp;                //{}
mp.insert(pair<string,int>("A",3));//{(A,3)}
mp.insert(pair<string,int>("B",1));//{(A,3),(B,1)}
mp.insert(pair<string,int>("C",2));//{(A,3),(B,1),(C,2)}
mp.insert(make_pair("D",4));       //{(A,3),(B,1),(C,2),(D,4)}
mp.insert(make_pair("A",4));       //{(A,3),(B,1),(C,2),(D,4)}

因为映射描述的是一种关系,涉及到两个元素,所以这里用pair这一类型类帮助我们插入。pair表示一个二元组,它的类型被<>定义。可以用如上两种方式创造一个pair变量。pair有两个域firstsecond,访问方式如下:

pair<string,int> temp=make_pair("A",4);
cout<<temp.first<<" "<<temp.second<<endl;

如果插入的原像已有对应的,那么这样的插入就是无效的,并不会替代原来的值。

(2)访问以及修改某一对映射的值

//{(A,3),(B,1),(C,2),(D,4)}
cout<<mp["B"]<<endl;//1
mp["B"]=10;
//{(A,3),(B,10),(C,2),(D,4)}
cout<<mp["B"]<<endl;//10
mp["E"]=2;
//{(A,3),(B,10),(C,2),(D,4),(E,2)}

访问map和访问数组几乎一致,修改的方式也是一样的,直接赋值即可。如果访问的原像并没有对应的,那么它就会创建一个新的映射。

(3)获取映射对个数size()

cout<<mp.size()<<endl;//5

注意一个可以有很多个原像,但一个原像不可以有多个。所以注意这里是映射对的数量,而不是的数量。

(4)查询某一个原像count()

//{(A,3),(B,10),(C,2),(D,4),(E,2)}
if(mp.count("A"))
    cout<<mp["A"]<<endl;

如果一个原像没有对应的,那么直接访问会报错。所以要先用count()查询是否存在之后再访问。

(5)遍历映射

for(map<string,int>::iterator it=mp.begin();it!=mp.end();it++)
{
    cout<<(*it).first<<" "<<(*it).second<<endl;
}

因为映射使用的不是连续空间,而是使用了迭代器,所以我们需要使用迭代器iterator来遍历映射。

注意s.begin()s.end()并不是整数,而是迭代器类型,所以it!=s.end()不能改成it<s.end()

遍历的结果是按照定义的顺序排列的。

(6)清空映射clear()

mp.clear();//{}

mapclear()不仅删除了元素,还清空了内存。

四、作业

1.vector

P3613 【深基15.例2】寄包柜

P2141 [NOIP2014 普及组] 珠心算测验

2.set

P1152 欢乐的跳

P5143 攀爬者

3.map

P1102 A-B 数对

P6402 [COCI2014-2015#2] UTRKA

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

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

相关文章

第四章快速排序——分而治之

分而治之&#xff08;divide and conquer,D&C&#xff09; D&C算法是递归的&#xff0c;并且有2个步骤&#xff1a; 找出基线条件&#xff0c;并且条件尽可能简单不断将问题分解&#xff0c;直到符合基线条件 给定一个数组&#xff0c;求和&#xff1a; 利用循环很容…

秒懂双向链表

目录 一、双向链表概述 二、模拟实现双向链表 1、头插法插入元素 2、尾插法插入元素 3、在指定位置插入元素 4、查询双向链表中是否包含key 5、删除第一次出现关键字为key的结点 6、删除所有值为key的结点 7、求双向链表的长度 8、遍历双向链表 9、清空双向链表 三…

【 uniapp - 黑马优购 | 商品列表 】如何实现数据获取、结构渲染、自定义组件的封装

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;讨厌编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc…

在 Mac 上将 PDF 转换为 Word 的 5 种简单方法

当谈到将PDF格式转换为Word格式时&#xff0c;用户可能会从互联网上搜索并尝试在线将PDF转换为Word。如果是这样&#xff0c;您可能会得到不好的结果并冒着文件本身的风险。在线 PDF 到 Word 转换器工具可能会产生低质量的输出&#xff0c;对文件大小有限制&#xff0c;更糟糕的…

maven多模块依赖版本不一致问题

项目结构&#xff1a; ├─springcloud-alibaba ├─.idea├─shop-common├─shop-order├─shop-product└─shop-user项目环境&#xff1a; 父工程&#xff1a; <properties><spring-cloud.version>Greenwich.RELEASE</spring-cloud.version><sprin…

java虚拟机之垃圾回收机制

一.需要回收的内存区域 程序计数器、虚拟机栈、本地方法栈 3 个区域随线程生灭(因为是线程私有)&#xff0c;栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。而 Java 堆和方法区则不一样&#xff0c;一个接口中的多个实现类需要的内存可能不一样&#xff0c…

<Focal Loss for Dense Object Detection>论文解读

目录1.简介2.模型2.1 二阶段要比单阶段模型效果好本质原因2.2 模型结构2.3.focal loss2.3.1 公式说明2.3.2 其他2.4 消融实验3.源码详解1.简介 目标识别有两大经典结构: 第一类是以Faster RCNN为代表的二阶段识别方法&#xff0c;这种结构的第一阶段专注于proposal的提取&am…

后端开发规约

目录 项目MVC层级设计规范 工程项目模块设计 设计规约 Java编码规范 参考《阿里巴巴Java开发手册》&#xff0c;见文末参考文档 OOP 面向对象设计 & 面向接口编程 Lombok工具包依赖 Guava、Hutool 等脚手架工具包&#xff08;三方包使用其一即可&#xff09; 日志打…

python初级教程十 Mongodb增、删、改、查

Mongodb 插入文档 MongoDB 中的一个文档类似 SQL 表中的一条记录。 插入集合 集合中插入文档使用 insert_one() 方法&#xff0c;该方法的第一参数是字典 name > value 对。 以下实例向 sites 集合中插入文档&#xff1a; #!/usr/bin/python3import pymongomyclient p…

03、Java并发 Java 线程池 ( Thread Pool ) (上)

本文我们将讲解 Java 中的线程池 ( Thread Pool )&#xff0c;从 Java 标准库中的线程池的不同实现开始&#xff0c;到 Google 开发的 Guava 库的前世今生。 本章节涉及到很多前几个章节中阐述的知识点。我们希望你是按照顺序阅读下来的&#xff0c;不然有些知识会一头雾水。 J…

Redis基础篇——Redis安装以及配置文件的修改

文章目录1. 认识Redis1.1 特征1.2 安装 Redis1. 安装 Redis 依赖2. 上传安装包1.3 默认启动1.4 指定配置启动1.5 开机自启&#xff08;推荐&#xff09;1. 认识Redis Redis 诞生于 2009 年&#xff0c;全称是 Remote Dictionary Server&#xff0c;远程词典服务器&#xff0c;…

Databend 开源周报 #73

Databend 是一款强大的云数仓。专为弹性和高效设计&#xff0c;自由且开源。 即刻体验云服务&#xff1a;https://app.databend.com。 What’s New 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 Features & Improvements Multiple Catalogs …

hudi实战-- 核心点解析

目录 Hudi 基础功能 Hudi 简介 Hudi 功能 Hudi 的特性 Hudi 的 架构 Hudi 数据管理 Hudi 表数据结构 hoodie 文件 数据文件 数据存储概述 Metadata 元数据 Index 索引 索引策略 Data 数据 Hudi 核心点解析 基本概念 时间轴Timeline 文件管理 索引 Index 表的存储…

NiN详解

入门小菜鸟&#xff0c;希望像做笔记记录自己学的东西&#xff0c;也希望能帮助到同样入门的人&#xff0c;更希望大佬们帮忙纠错啦~侵权立删。 ✨完整代码在我的github上&#xff0c;有需要的朋友可以康康✨ https://github.com/tt-s-t/Deep-Learning.git 目录 一、NiN网络的…

【C语言开源库】 一个只有500行代码的开源http服务器:Tinyhttpd学习

项目搬运&#xff0c;带中文翻译&#xff1a;https://github.com/nengm/Tinyhttpd在嵌入式中&#xff0c;我们HTTP服务器用得最多的就是boa还有就是goahead,但是这2个代码量比较大&#xff0c;而Tinyhttpd只有几百行&#xff0c;比较有助于我们学习。一、编译及运行直接make之后…

用Python让奇怪的想法变成现实,2023年继续创作

2023年继续写作&#xff0c;用文章记录生活 时间过得真快&#xff0c;一下就到2023年了。 由于疫情肆虐&#xff0c;在网络的游弋的实现也长了&#xff0c;写作的自然也多了。 回想一下&#xff0c;2018-2021年这三年时间里一篇文章也没写过为0&#xff0c;哈哈&#xff0c;没…

【EHub_tx1_tx2_E100】Ubuntu18.04 + ROS_ Melodic + NVISTAR VP300 激光雷达 评测

简介&#xff1a;介绍NVISTAR 的二维DTOF激光雷达 在EHub_tx1_tx2_E100载板&#xff0c;TX1核心模块环境&#xff08;Ubuntu18.04&#xff09;下测试ROS驱动&#xff0c;打开使用RVIZ 查看点云数据&#xff0c;本文的前提条件是你的TX1里已经安装了ROS版本&#xff1a;Melodic。…

滴滴前端一面经典手写面试题

实现bind 实现bind要做什么 返回一个函数&#xff0c;绑定this&#xff0c;传递预置参数bind返回的函数可以作为构造函数使用。故作为构造函数时应使得this失效&#xff0c;但是传入的参数依然有效 // mdn的实现 if (!Function.prototype.bind) {Function.prototype.bind f…

Kuberneters(2)- Pod详解

第四章 实战入门 本章节将介绍如何在kubernetes集群中部署一个nginx服务&#xff0c;并且能够对其进行访问。 Namespace ​ Namespace是kubernetes系统中的一种非常重要资源&#xff0c;它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。 ​ 默认情况下&…

路由跳转同一个界面,但是params不同。页面不刷新?(路由的key)

文章目录引入知识点&#xff1a;路由的key值思路&#xff1a;结论&#xff1a;解决方法&#xff1a;效果&#xff1a;应用场景:引入知识点&#xff1a;路由的key值 如果不设置路由的key值&#xff0c;默认情况下是根据路径判断的&#xff0c;就是不包括params值 例子&#xff…