map 和 set 的使用

文章目录

  • 一.序列式容器和关联式容器
  • 二. set 系列的使用
    • 1. set 和 multiset 参考文档
    • 2. set 类介绍
    • 3. set 的构造和迭代器
    • 4. set 的增删查
    • 5. insert 和迭代器遍历使用样例
    • 6. find 和 erase 使用样例
    • 7. multiset 和 set 的差异
  • 三. map 系列的使用
    • 1. map 和 multimap参考文档
    • 2. map 类介绍
    • 3. pair 类型介绍
    • 4. map 的构造
    • 5. map 的增删查
    • 6. map 的数据修改
    • 7. 构造遍历及增删查使用样例
    • 8. map 的迭代器和 [ ] 功能介绍
    • 9. multimap 和 map 的差异


一.序列式容器和关联式容器

STL中部分容器如string、vector、list、deque、array、forward_list等,这些容器统称为序列式容器,因为逻辑结构为线性序列的数据结构,两个位置储存的值之间一般没有紧密的关联,如果交换一下,他依旧是序列式容器。顺序容器中的元素按他们在容器中的存储位置来顺序保存和访问

关联式容器也是用来存储数据的,与序列式容器不同的是,关联式容器逻辑结构通常是非线性结构,两个位置有紧密的关联,如果交换一下,他的存储结构就被破坏了。关联式容器中的元素是按关键字来保存和访问的

关联式容器有 map / set 系列和 unordered_map / unordered_set 系列

本文要讲解的是 map 和 set (底层是红黑树),红黑树是一颗平衡二叉搜索树。set 是 key 搜索场景的结构,map 是 key / value 搜索场景的结构

二. set 系列的使用

1. set 和 multiset 参考文档

set 和 multiset 参考文档

2. set 类介绍

template < class T,                        // set::key_type/value_typeclass Compare = less<T>,        // set::key_compare/value_compareclass Alloc = allocator<T>      // set::allocator_type> class set;

(1)set 的声明如上,T 是 set 底层关键字的类型。

(2)set 默认要求T支持小于比较,如果不支持或者想按自己的需求走,可以自行实现仿函数传给第二个模板参数。

(3)set 底层存储数据的内存是从空间配置器申请的,如果需要可以自己实现内存池,传给第三个参数。

(4)一般情况下,都不需要传后两个模板参数。

(5)set 底层是用红黑树实现,增删查效率是O(logN),迭代器遍历是通过搜索树的中序,所有是有序的。

3. set 的构造和迭代器

set 的构造我们关注以下几个接口即可。

set 支持正向和反向迭代遍历,遍历默认按升序顺序,因为底层是二叉搜索树,迭代器遍历走的是中序;支持迭代器就意味支持范围for,set 的 iterator 和 const_iterator 都不支持迭代器修改数据,修改关键字数据会破坏底层搜索树的结构。

// empty (1) ⽆参默认构造
explicit set(const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());// range (2) 迭代器区间构造
template <class InputIterator>
set(InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type & = allocator_type());// copy (3) 拷⻉构造
set(const set& x);// initializer list (5) initializer 列表构造
set(initializer_list<value_type> il,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());// 迭代器是⼀个双向迭代器
iterator->a bidirectional iterator to const value_type// 正向迭代器
iterator begin();
iterator end();// 反向迭代器
reverse_iterator rbegin();
reverse_iterator rend();

4. set 的增删查

Member types
key_type->The first template parameter(T)
value_type->The first template parameter(T)// 单个数据插⼊,如果已经存在则插⼊失败
pair<iterator, bool> insert(const value_type& val);// 列表插⼊,已经在容器中存在的值不会插⼊
void insert(initializer_list<value_type> il);// 迭代器区间插⼊,已经在容器中存在的值不会插⼊
template <class InputIterator>
void insert(InputIterator first, InputIterator last);// 查找val,返回val所在的迭代器,没有找到返回end()
iterator find(const value_type& val);// 查找val,返回Val的个数
size_type count(const value_type& val) const;// 删除⼀个迭代器位置的值
iterator erase(const_iterator position);// 删除val,val不存在返回0,存在返回1
size_type erase(const value_type& val);// 删除⼀段迭代器区间的值
iterator erase(const_iterator first, const_iterator last);// 返回⼤于等val位置的迭代器
iterator lower_bound(const value_type& val) const;// 返回⼤于val位置的迭代器
iterator upper_bound(const value_type& val) const;

5. insert 和迭代器遍历使用样例

在这里插入图片描述

6. find 和 erase 使用样例

样例1:

#include<iostream>
#include<set>
using namespace std;
int main()
{set<int> s = { 4,2,7,2,8,5,9 };for (auto e : s){cout << e << " ";} cout << endl;// 删除最⼩值s.erase(s.begin());for (auto e : s){cout << e << " ";}cout << endl;// 直接删除xint x;cin >> x;int num = s.erase(x);if (num == 0){cout << x << "不存在!" << endl;} for (auto e : s){cout << e << " ";} cout << endl;// 直接查找在利⽤迭代器删除xcin >> x;auto pos = s.find(x);if (pos != s.end()){s.erase(pos);} else{cout << x << "不存在!" << endl;}for (auto e : s){cout << e << " ";} cout << endl;// 算法库的查找 O(N)auto pos1 = find(s.begin(), s.end(), x);// set⾃⾝实现的查找 O(logN)auto pos2 = s.find(x);// 利⽤count间接实现快速查找cin >> x;if (s.count(x)){cout << x << "在!" << endl;} else{cout << x << "不存在!" << endl;} return 0;
}

在这里插入图片描述

样例2:
在这里插入图片描述

7. multiset 和 set 的差异

multiset和set的使用基本完全类似,主要区别点在于multiset⽀持值冗余。因此insert/find/count/erase都围绕着⽀持值冗余有所差异。

在这里插入图片描述

三. map 系列的使用

1. map 和 multimap参考文档

map 和 multimap参考文档

2. map 类介绍

template < class Key, // map::key_typeclass T, // map::mapped_typeclass Compare = less<Key>, // map::key_compareclass Alloc = allocator<pair<const Key, T> > //map::allocator_type
> class map;

(1)map 的声明如上,T 是 map 底层value的类型。

(2)map 底层存储数据的内存是从空间配置器申请的。

(4)一般情况下,都不需要传后两个模板参数。

(5)map 底层是用红黑树实现,增删查效率是O(logN),迭代器遍历是通过搜索树的中序,按 key 的有序顺序遍历。

3. pair 类型介绍

map 底层的红黑树节点中的数据,使用 pair<Key,T>存储键值对数据。

typedef pair<const Key, T> value_type;template <class T1, class T2>
struct pair
{typedef T1 first_type;typedef T2 second_type;T1 first;T2 second;pair() : first(T1()), second(T2()){}pair(const T1& a, const T2& b) : first(a), second(b){}template<class U, class V>pair(const pair<U, V>& pr) : first(pr.first), second(pr.second){}
};template <class T1, class T2>
inline pair<T1, T2> make_pair(T1 x, T2 y)
{return (pair<T1, T2>(x, y));
}

4. map 的构造

map 的构造我们关注以下几个接口即可。

map 支持正向和反向迭代遍历,遍历默认按 ke y的升序顺序,因为底层是二叉搜索树,迭代器遍历走的中序;支持迭代器就意味着支持范围for,map 支持修改 value 数据,不支持修改 key 数据,修改关键字数据,会破坏底层搜索树的结构。

// empty (1) ⽆参默认构造
explicit map(const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());// range (2) 迭代器区间构造
template <class InputIterator>
map(InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type & = allocator_type());// copy (3) 拷⻉构造
map(const map& x);// initializer list (5) initializer 列表构造
map(initializer_list<value_type> il,const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());// 迭代器是⼀个双向迭代器
iterator->a bidirectional iterator to const value_type// 正向迭代器
iterator begin();
iterator end();// 反向迭代器
reverse_iterator rbegin();
reverse_iterator rend();

5. map 的增删查

map 增接口,插入的 pair 键值对数据,跟 set 有所不同,但是查和删的接口只用关键字 key 跟 set 是完全类似的,不过 find 返回 iterator,不仅仅可以确认 key 在不在,还找到 key 映射的 value, 同时通过迭代还可以修改 value。

Member types
key_type->The first template parameter(Key)
mapped_type->The second template parameter(T)
value_type->pair<const key_type, mapped_type>// 单个数据插⼊,如果已经key存在则插⼊失败,key存在相等value不相等也会插⼊失败
pair<iterator, bool> insert(const value_type& val);// 列表插⼊,已经在容器中存在的值不会插⼊
void insert(initializer_list<value_type> il);// 迭代器区间插⼊,已经在容器中存在的值不会插⼊
template <class InputIterator>
void insert(InputIterator first, InputIterator last);// 查找k,返回k所在的迭代器,没有找到返回end()
iterator find(const key_type& k);// 查找k,返回k的个数
size_type count(const key_type& k) const;// 删除⼀个迭代器位置的值
iterator erase(const_iterator position);// 删除k,k存在返回0,存在返回1
size_type erase(const key_type& k);// 删除⼀段迭代器区间的值
iterator erase(const_iterator first, const_iterator last);// 返回⼤于等k位置的迭代器
iterator lower_bound(const key_type& k);// 返回⼤于k位置的迭代器
const_iterator lower_bound(const key_type& k) const;

6. map 的数据修改

map 支持修改 mapped_type 数据,不支持修改 key 数据,修改关键字数据,破坏了底层搜索树的结构。

map 第一个支持修改的方式是通过迭代器,迭代器遍历时或者 find 返回 key 所在的 iterator 修改,map 还有一个非常重要的修改接口 operator[ ] ,但是 operator[ ] 不仅仅支持修改,还支持插入数据和查找数据,所有他是一个多功能复合接口。

map 这里把我们传统说的 value 值,给的是 T 类型,typedef 为 mapped_type。而 value_type 是红黑树结点中存储的 pair 键值对值。

Member types
key_type->The first template parameter(Key)
mapped_type->The second template parameter(T)
value_type->pair<const key_type, mapped_type>// 查找k,返回k所在的迭代器,没有找到返回end(),如果找到了通过iterator可以修改key对应的mapped_type值
iterator find(const key_type& k);// insert插⼊⼀个pair<key, T>对象
// 1、如果key已经在map中,插⼊失败,则返回⼀个pair<iterator,bool>对象,返回pair对象first是key所在结点的迭代器,second是false
// 2、如果key不在在map中,插⼊成功,则返回⼀个pair<iterator,bool>对象,返回pair对象first是新插⼊key所在结点的迭代器,second是true
// 也就是说⽆论插⼊成功还是失败,返回pair<iterator,bool>对象的first都会指向key所在的迭代器
// 那么也就意味着insert插⼊失败时充当了查找的功能,正是因为这⼀点,insert可以⽤来实现operator[]
// 需要注意的是这⾥有两个pair,不要混淆了,⼀个是map底层红⿊树节点中存的pair<key, T>,另⼀个是insert返回值pair<iterator, bool>
pair<iterator, bool> insert(const value_type & val);mapped_type& operator[] (const key_type& k);// operator的内部实现
mapped_type& operator[] (const key_type& k)
{// 1、如果k不在map中,insert会插⼊k和mapped_type默认值,同时[]返回结点中存储mapped_type值的引⽤,那么我们可以通过引⽤修改返映射值。所以[]具备了插⼊ + 修改功能// 2、如果k在map中,insert会插⼊失败,但是insert返回pair对象的first是指向key结点的迭代器,返回值同时[]返回结点中存储mapped_type值的引⽤,所以[]具备了查找 + 修改的功能pair<iterator, bool> ret = insert({ k, mapped_type() });iterator it = ret.first;return it->second;
}

7. 构造遍历及增删查使用样例

#include<iostream>
#include<map>
using namespace std;
int main()
{// initializer_list构造及迭代遍历map<string, string> dict = { {"left", "左边"}, {"right", "右边"},{"insert", "插入"},{ "string", "字符串" } };//map<string, string>::iterator it = dict.begin();auto it = dict.begin();while (it != dict.end()){//cout << (*it).first <<":"<<(*it).second << endl;// map的迭代基本都使用operator->,这⾥省略了一个->// 第一个->是迭代器运算符重载,返回pair*,第二个箭头是结构指针解引⽤取pair数据//cout << it.operator->()->first << ":" << it.operator->()-> second << endl;cout << it->first << ":" << it->second << endl;++it;}cout << endl;// insert插入pair对象的4种方式,对⽐之下,最后⼀种最方便pair<string, string> kv1("first", "第一个");dict.insert(kv1);dict.insert(pair<string, string>("second", "第二个"));dict.insert(make_pair("sort", "排序"));dict.insert({ "auto", "自动的" });// "left"已经存在,插⼊失败dict.insert({ "left", "左边,剩余" });// 范围for遍历for (const auto& e : dict){cout << e.first << ":" << e.second << endl;} cout << endl;string str;while (cin >> str){auto ret = dict.find(str);if (ret != dict.end()){cout << "->" << ret->second << endl;}else{cout << "无此单词,请重新输入" << endl;}} // erase等接⼝跟set完全类似,这⾥就不演示讲解了return 0;
}

在这里插入图片描述

8. map 的迭代器和 [ ] 功能介绍

样例1:
在这里插入图片描述
样例2:
在这里插入图片描述
样例3:
在这里插入图片描述

9. multimap 和 map 的差异

multimap 和 map 的使用基本完全类似,主要区别点在于 multimap 支持关键字 key 冗余。 因insert/find/count/erase都围绕着支持关键字 key 冗余有所差异,这里 set 和 multiset 完全一样,例如 find 时,有多个 key,返回中序第一个

multimap 不支持 [ ] ,因为支持 key 冗余,[ ] 就只能支持插入,不能支持修改。

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

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

相关文章

【Spring】Spring Boot 日志(8)

本系列共涉及4个框架&#xff1a;Sping,SpringBoot,Spring MVC,Mybatis。 博客涉及框架的重要知识点&#xff0c;根据序号学习即可。 1、日志概述 1.1学习日志的必要性 在第一次学习编程语言的时候&#xff0c;我们就在使用printf或者System.out.println等打印语句打印日志了…

Python超轻量对话框:easyGUI

文章目录 简介box回调函数 简介 EasyGUI是一个非常简单的GUI模块&#xff0c;提供了许多对话框&#xff0c;所有交互操作都通过简单的函数调用实现。支持pip安装&#xff0c;十分便捷 pip install easygui通过一行代码&#xff0c;即可实现下面的对话框 其对应的代码为 impo…

ArrayList和Array、LinkedList、Vector 间的区别

一、ArrayList 和 Array 的区别 ArrayList 内部基于动态数组实现&#xff0c;比 Array&#xff08;静态数组&#xff09; 使用起来更加灵活&#xff1a; ArrayList 会根据实际存储的元素动态地扩容或缩容&#xff0c;而 Array 被创建之后就不能改变它的长度了。ArrayList 允许…

雷池社区版OPEN API使用教程

OPEN API使用教程 新版本接口支持API Token鉴权 接口文档官方没有提供&#xff0c;有需要可以自行爬取&#xff0c;爬了几个&#xff0c;其实也很方便 使用条件 需要使用默认的 admin 用户登录才可见此功能版本需要 > 6.6.0 使用方法 1.在系统管理创建API TOKEN 2.发…

OpenGMS是什么?如何使用OpenGMS的建模与模拟工具(一)

目录 OpenGMS是什么&#xff1f;如何使用OpenGMS的建模与模拟工具&#xff08;一&#xff09; 一、什么是OpenGMS 1、OpenGMS网站 2、OpenGMS团队 二、为什么我们需要OpenGMS 1、地理模拟实验的局限性区域性限制了科研应用的效率 2、外界对于OpenGMS的评价 三、 OpenG…

springboot095学生宿舍信息的系统--论文pf(论文+源码)_kaic

学生宿舍信息管理系统 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了学生宿舍信息管理系统的开发全过程。通过分析学生宿舍信息管理系统管理的不足&#xff0c;创建了一个计算机管理学生宿舍信息管理系统的方…

五、大模型(LLMs)RAG检索增强生成面

本文精心汇总了多家顶尖互联网公司在大模型RAG检索增强生成考核中的核心考点&#xff0c;并针对这些考点提供了详尽的解答。并提供电子版本&#xff0c;见于文末百度云盘链接中&#xff0c;供读者查阅。 5.1 大模型&#xff08;LLMs&#xff09;RAG 入门篇 基于LLM向量库的文档…

VGG16

1️⃣ VGG介绍 Alexnet证明了神经网络变深是有效的&#xff0c;因此网络能不能更深更大&#xff1f;   VGG&#xff08;visual geometry group&#xff09;是由牛津大学提出的使用“块思想”的网络&#xff0c;通过使用循环和子程序可以很容易地在任何现代深度学习框架的代码…

Transformer多步时序预测:多变量输入,单变量输出

文章目录 Transformer类数据集类训练函数测试函数画图计算指标读取数据计时开始训练 数据集来源&#xff1a; https://github.com/zhouhaoyi/ETDataset import torch import torch.nn as nn import numpy as np import pandas as pd import math import time from sklearn.pre…

RabbitMq-队列交换机绑定关系优化为枚举注册

&#x1f4da;目录 &#x1f4da;简介:&#x1f680;比较&#x1f4a8;通常注册&#x1f308;优化后注册 ✍️代码&#x1f4ab;自动注册的关键代码 &#x1f4da;简介: 该项目介绍&#xff0c;rabbitMq消息中间件&#xff0c;对队列的注册&#xff0c;交换机的注册&#xff0c…

使用pyinstaller将python代码打包为exe程序

打包exe 对于不懂程序的人来说&#xff0c;可能有这样一个认识上的误区&#xff1a;只有能够直接打开的exe才是平常经常见到的程序&#xff0c;py文件不能算是程序。 在这种情况下&#xff0c;一些python的使用者可能非常苦恼&#xff1a;怎么才能够让我的程序&#xff0c;看…

博客搭建之路:hexo搜索引擎收录

文章目录 hexo搜索引擎收录以百度为例 hexo搜索引擎收录 hexo版本5.0.2 npm版本6.14.7 next版本7.8.0 写博客的目的肯定不是就只有自己能看到&#xff0c;想让更多的人看到就需要可以让搜索引擎来收录对应的文章。hexo支持生成站点地图sitemap 在hexo下的_config.yml中配置站点…

2-ZYNQ 折腾记录 -PMU

The AMD Zyng UltraScale MPSoC包括一个专用的用户可编程处理器&#xff0c;该平台测量单元(Platform Measurement Unit, PMU)处理器用于电源、错误管理和执行可选的软件测试库(Software Test Library, STL)用于功能安全应用。 PMU执行以下一组任务。启动前对系统的初始化。电…

Video-XL:面向小时级视频理解的超长视觉语言模型

在人工智能领域&#xff0c;视频理解一直是一个挑战性的任务&#xff0c;尤其是对于长时间视频内容的理解。现在&#xff0c;Video-XL的问世标志着我们在这一领域迈出了重要的一步。Video-XL是一个专为小时级视频理解设计的超长视觉语言模型&#xff0c;它能够处理超长视频序列…

BUUCTF之web篇

第一题 [极客大挑战 2019]EasySQL 打开靶机后可以看到这是一个登陆的页面 我们可以尝试两种方式登录 弱口令爆破&#xff08;burpsuite&#xff09; 通过SQL注入里的万能密码来跳过账户和密码验证的过程 这里就需要万能密码aor true # 在这里单引号的作用是结束用户名或者密码…

【Javaee】网络原理—http协议(一)

前言 本篇文章将详细介绍http协议&#xff0c;将介绍http抓包工具的下载与使用。 目录 一.http协议初识 1.概念 2.特点 1&#xff09;版本 2&#xff09;工作方式 二.http抓包工具 1.抓包是什么 2.抓包软件下载&#xff08;Fiddler&#xff09; 3.使用 三.http格式 …

04C++循环结构

//while 循环#include <iostream> using namespace std; int main() { int num0; while (num<10){ cout<<num<<endl; num; } return 0; } //do while语句 #include <iostream> using namespace std; int mai…

Appium中的api(一)

目录 1.基础python代码准备 1--参数的一些说明 2--python内所要编写的代码 解释 2.如何获取包名和界面名 1-api 2-完整代码 代码解释 3.如何关闭驱动连接 4.安装卸载app 1--卸载 2--安装 5.判断app是否安装 6.将应用放到后台在切换为前台的时间 7.UIAutomatorViewer的使用 1--找…

并联 高电压、高电流 放大器实现 2 倍输出电流模块±2A

1.1 并联输出电路设计注意事项 直接对两个功率运算放大器的输出进行硬接线并不是一种好的电气做法。如果两个运算放大器的输出直接连接在一起&#xff0c;则可能会导致不均匀的电流共享。这是因为其中的每个运算放大器都尝试强制施加略微不同的 Vout 电压&#xff0c;该电压取决…

vulnhub(16):sickos(两种打点方式)

端口 ip&#xff1a;192.168.72.154 nmap -Pn -p- 192.168.72.154 --min-rate 10000PORT STATE SERVICE 22 open ssh 3128 open http-proxy 8080 closed http-proxy web渗透方式一&#xff1a;web后台 正常访问80端口&#xff0c;是不开放的&#xff0c;我们需要配置…