C++ - map,set

news/2024/12/11 18:54:05/

set和map介绍

map 和 set 是C++ STL 中提供的容器, map 和 set 的底层是基于红黑树来实现的.

set 是一个包含唯一元素 (key) 的集合,不允许有重复的元素.

map 是一个键值对 (key - value) 的集合, 每一个键 (key) 都是唯一的.

map 的key - value键值对是通过 pair 来实现的.

可以观察到, map 比 set 多一个模板参数.
set 只有 T, 而 map 有key 和 T.

set 和 map 底层既然是基于 红黑树 来实现的, 那么set 和 map 中的数据都是唯一且有序的, 并不允许存在重复的数据. set 和 map 也不持支改的操作, 只支持增删查.

pair结构

map 中存储的数据是键值对. 而 pair 实际上就是一个键值对的结构.
所以在 map 中实际存储的类型就是 pair.

pair是一个模板类,用于存储两个相关联的值.

可以看到 pair 有两个类型模板参数 T1 和 T2.

template<class T1, class T2>
struct pair
{T1 first;T2 second;pair():first(T1()),second(T2()){}pair(const T1& a, const T2& b):first(a),second(b){}
};

可以看到就是一个非常简单的数据结构, 里面存储两个变量, 没啥特别的.
两个变量的类型可以相同也可以不同, 使用灵活.

map 中就是使用这个 pair 结构来存储 key 和 value 的.
first 对应 key
second 对应 value.

map使用

map 的插入, 调用 insert 成员函数. 
插入成功, 就会返回一个 pair 类型的数据.

pair<iterator, bool>

可以看到返回的 pair 类型, first 是map的迭代器, 第二个则是 bool 类型, 代表本插入是否成功.

map<string, string> dict;// 1. 直接创建一个对应类型的 pair
pair<string, string> kv1("树", "tree");
pari<string, string> kev2("栈", "stack");
dict.insert(kv1);
dict.insert(kv2);// 2. 使用匿名对象插入
dict.insert(pair<string, string>("队列", "queue");// 3. 使用 make_pair 插入, mak_pair 是一个函数模板
// 会用传入的两个值创建出一个 pair 类型返回
template <class T1,class T2>
pair<T1,T2> make_pair (T1 x, T2 y)
{return ( pair<T1,T2>(x,y) );
}dict.insert(make_pair("链表", "list"));

map 的删除, 使用 erase 函数

map<string, string> dict;dict.insert(make_pair("链表", "list"));
dict.insert(make_pair("队列", "queue"));dict.erase("链表"); // 通过 pair 中的 first 来查找, 并删除

map 的查找, 使用 find 函数
会返回一个查找的数据的迭代器.

map<string, string> dict;dict.insert(make_pair("链表", "list"));
dict.insert(make_pair("队列", "queue"));std::map<string, string>::iterator = dict .find("链表");
cout << it->first << ": " << it->second;

map 中用的最多的还是 operator[].
operator[] 有 insert 和 find 的功能. 

operator[] 会先去查找 map 中是否存在这个 key,

如果存在则返回这个键值对中 value 的引用. 就是 pair 中的 second 的引用

如果不存在, 则会在 map 中先插入这个 key, value 调用 value 类型的默认构造创建一个默认值. 此时 key 就存在了, 然后和上面一样, 返回 value 的引用.

operator[] == (*((this->insert(make_pair(k,mapped_type()))).first)).second

int main ()
{std::map<char,std::string> mymap;mymap['a']="an element";// 没有找到 'a' 这个键, 那么就会先插入 'a'.// 然后返回 value 的引用, value 通过 = 被赋值为"an element"mymap['b']="another element"; // 'b' 和 'a' 是一样的mymap['c']=mymap['b']; // 将 'b' 的 value 赋值给 'c'std::cout << "mymap['a'] is " << mymap['a'] << '\n';std::cout << "mymap['b'] is " << mymap['b'] << '\n';std::cout << "mymap['c'] is " << mymap['c'] << '\n';std::cout << "mymap['d'] is " << mymap['d'] << '\n';return 0;
}

set使用

set 的插入, 调用成员函数 insert
和 map 的插入函数一样, 会返回一个 pair 类型数据

pair<iterator, bool>

first 是 set 的迭代器, second 是 bool 类型, 表示本次插入是否成功

set<int> myset;myset.insert(10);
myset.insert(20);

set 的查找, find 函数
和 map 的 find 一样, 返回一个 set 的迭代器

set<int> myset;myset.insert(10);
myset.insert(20);std::set<int>::iterator it;
it = myset,find(10);cout << *it << endl;

set 的删除, erase 函数

set<int> myset;myset.insert(10);
myset.insert(20);myset.erase (10);

multimap和multiset

在 map 和 set 中, 所有的元素都是唯一的, 不能重复.
但是在 STL 提供的 multimap 和 multiset 中,
是能存在相同的元素的.

但是在实际中用的不太多, 了解即可


http://www.ppmy.cn/news/1554296.html

相关文章

互联网、物联网的相关标准

互联网的相关标准 网络通信协议&#xff1a; HTTP&#xff08;Hypertext Transfer Protocol&#xff09;&#xff1a;用于在网络中传输文本、图像、音频和视频等数据的协议。它基于请求-响应模型&#xff0c;客户端发送请求给服务器&#xff0c;服务器返回响应。HTTPS&a…

zookeeper 搭建集群

基础的java 环境先安好&#xff0c;选择3台虚拟机 ip 不一样 机器应为奇数个 zookeeper 奇数个节点实际上是(2*n-1) 比偶数台机器少一台解决成本,并且能够满足 zookeeper 集群过半选举leader 的规则 # 3台虚拟机 将zookeeper 解压到服务器上 #在 conf/ 目录下 找到zoo_s…

Spring Boot 中 WebClient 的实践详解

在现代微服务架构中&#xff0c;服务之间的通信至关重要。Spring Boot 提供了 WebClient&#xff0c;作为 RestTemplate 的替代方案&#xff0c;用于执行非阻塞式的 HTTP 请求。本文将详细讲解 WebClient 的实践&#xff0c;包括配置、使用场景以及常见的优化策略&#xff0c;帮…

巧用缓存:高效实现基于 read4 的文件读取方法

文章目录 摘要描述题目描述要求read4 方法定义read 方法定义 题解答案题解代码题解代码分析示例测试及结果示例测试代码示例运行结果 时间复杂度空间复杂度总结关于我们 摘要 本篇文章将探讨一道经典的编程题&#xff1a;通过 read4 方法实现读取 n 个字符的功能。我们将详细介…

node(multer)上传文件

node(multer)上传文件 from表单上传文件 前端代码 import React from react; import { Form, Button, Upload, message } from antd; import { UploadOutlined } from ant-design/icons; import axios from axios;const FileUploadForm () > {const onFinish async (va…

Three.js曲线篇 8.管道漫游

目录 创建样条曲线 创建管道 透视相机漫游 完整代码 大家不要被这个“管道漫游”这几个字所蒙骗了&#xff0c;学完后大家就知道这个知识点有多脏了。我也是误入歧途&#xff0c;好奇了一下“管道漫游”。好了&#xff0c;现在就给大家展示一下为啥这个只是点脏了。 我也废话…

用友U8+ API接口使用教程

前言 U8和其他的公开的开放API接口有一些差异&#xff0c;他是需要先对接的到代理服务器&#xff0c;通过代理服务器进行对接&#xff0c;所以只要保证U8能上网就能对接&#xff0c;和畅捷通T的模式有点类似 流程&#xff1a; 注册成为开发者&#xff08;用于创建用友U8 API应…

解决uview ui赋值后表单无法通过验证

微信小程序中 主要还是文档有这样一段话&#xff1a;//如果需要兼容微信小程序&#xff0c;并且校验规则中含有方法等&#xff0c;只能通过setRules方法设置规则。 添加即可通过 onReady() {//如果需要兼容微信小程序&#xff0c;并且校验规则中含有方法等&#xff0c;只能通过…