C++轮子 · STL关联容器

上一篇文章中我们简单的介绍了一下STL中的序列容器和容器适配器,这篇文章中我们将重点介绍STL中的关联容器(最后四个在概念上应该不是关联容器,但是因为和前面的容器联系太紧密,统一放在这里讲解),主要内容包括:

  • std::set
  • std::map
  • std::multi_map
  • std::multi_set
  • std::unordered_map
  • std::unordered_set
  • std::unordered_multimap
  • std::unordered_multiset

std::set

通常提到关联容器,大家可能首先会想到的是std::map,这里先讲解std::set是避免出现关联数组关联容器概念上的混淆。前者是数据结构中的概念,而后则是C++中特有的概念。

什么关联容器

关联容器这个概念,在C++里面是一个Concept(关于concept的讨论我们在上一篇文章中有讲解,这里不再赘述),它的基本定义如下:

An AssociativeContainer is an ordered Container that provides fast lookup of objects based on keys.

翻译成中文,大概是说关联容器是提供了基于key的快速查找功能的有序容器。它实际上是 Container 这个 Concept 的 Refinement。

Refinement

Refinement 在泛型编程中是一个非常重要的概念,它和 Concept 的关系类似于OO世界中父子继承关系。我们知道 Concept 表示的不是一个类型而是一个类型集合,所以 Refinement 表示的其实也是一个类型集合,这些类型比 Concept 中的定义的类型要有更多的约束和特性(约束和特性其实是一个问题的两个方面,你约束的越是严格,你能够使用的特性越多,但是你能使用的场景越少,比如 Java 中 Object 类哪儿都能用,又哪儿都用不了)。

有序

在数学概念上,集合表示具有某种特定性质的事物的总体,它有三个特性:无序性、互异性、确定性。

个人认为,C++世界里面的std::set其实并不是传统意义上的集合,因为它不符合无序的特性(当然你也可以理解成无序表示任何顺序都可以,有序也属于无序的一种状态)。

Key 值的只读属性

需要特别提醒的是,因为关联容器使用key值排序,你不能修改key值,否则你会破坏关联容器的内部结构(虽然有些情况下更改key值在逻辑上是合理并且合法的【1】)。在C++11之后,关联容器返回的迭代器,key都默认是const。如果你需要更改key的值,最好的方式是先删除,再插入(有move的存在,这一步的开销相对小一些)。

互异

互异是指集合内部的任意两个元素都不相同,这一点在std::set中满足,但是在std::multi_set中并不满足。

std::set元素的互异在编程中有一个非常大的作用是去重,当然你也可以使用sort+unique的方式来处理去重,但是std::set的方式在逻辑上更具有表达力。

成员方法

std::set中的很多成员和std::map类似,只不过它们的value_type不一样,std::set<std::string>value_typestd::string,而std::map<int, std::string>value_typestd::pair<const int, std::string>。因此这一小节不介绍相关的成员函数,你可以查看std::map的相关成员函数的介绍,然后对照std::set的文档来理解这一部分内容。

std::map

std::map可能是C++世界使用得最广泛的关联容器,它以键值对的形式存储数据的一种关联容器,可以用于充当关联数组。

关联数组

在数据结构的范畴里面,map又被称为关联数组。一个普通的数组,可以使用int(严格来说应该是size_t)做为下标来访问数组内部的元素,关联数组则可以使用任意类型做为下标来存取数组内部的数组。当然这里说的数组是一个逻辑上的概念,关联数组的实现物理上的实现通常是树或者哈希表等等。

需要注意的是关联数组和关联容器是完全不同的两个概念,关联容器强调的是提供快速访问的有序容器,这个概念只存在于C++中;而关联数组强调的是键值对的形式存储数据,并通过key来快速访问数据,这个概念是传统数据结构中的概念,在不同的语言对应不同的类型,比如Java的map,Python的dict。关联容器不一定是关联数组,比如set;关联数组也不一定是关联容器,比如unordered_map。

红黑树

map和set的实现通常是一个颗红黑树,红黑树是一种平衡二叉排序树。它的节点要么是黑要么是红,但是

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

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

相关文章

推荐新版AI智能聊天系统网站源码ChatGPT NineAi

Nine AI.ChatGPT是基于ChatGPT开发的一个人工智能技术驱动的自然语言处理工具&#xff0c;它能够通过学习和理解人类的语言来进行对话&#xff0c;还能根据聊天的上下文进行互动&#xff0c;真正像人类一样来聊天交流&#xff0c;甚至能完成撰写邮件、视频脚本、文案、翻译、代…

GoZero微服务个人探究之路(七)添加中间件、自定义中间件

说在前面 官方已经自己实现了很多中间件&#xff0c;我们可以方便的直接使用&#xff0c;不用重复造轮子了 开启方式可以看官方文档 中间件 | go-zero Documentation 实现自定义的中间件 在业务逻辑中&#xff0c;我们需要实现自定义功能的中间件 ------这里我们以实现跨源…

Typescript的类型推导与联合类型

考虑以下 TypeScript 代码片段&#xff1a; function processInput(input: string | number): void {if (typeof input "string") {console.log(Input is a string: ${input.toUpperCase()});} else if (typeof input "number") {console.log(Input is …

Spring+SprinMVC+MyBatis配置方式简易模板

SpringSprinMVCMyBatis配置方式简易模板代码Demo GitHub访问 ssm-tpl-cfg 一、SQL数据准备 创建数据库test&#xff0c;执行下方SQL创建表ssm-tpl-cfg /*Navicat Premium Data TransferSource Server : 127.0.0.1Source Server Type : MySQLSource Server Versio…

Linux ---- 小玩具

目录 一、安装&#xff1a; 1、佛祖保佑&#xff0c;永不宕机&#xff0c;永无bug 2、小火车 3、艺术字和其它 天气预报 艺术字 4、会说话的小牦牛 5、其他趣味图片 我爱你 腻害 英雄联盟 帅 忍 龙 你是猪 福 好运连连 欢迎 加油 想你 忘不了你 我错了 你…

细说JavaScript事件处理(JavaScript事件处理详解)

js语言的一个特色和就是它的动态性&#xff0c;即一时间驱动的方式对用户输入作出反应而不需要依赖服务器端程序。事件是指人机交互的结果&#xff0c;如鼠标移动、点击按钮、在表单中输入数据或载入新的Web洁面等。 一、什么是事件 1、事件类型 1.1、事件源 1.2、事件处理…

Node.js Stream.pipeline() Method

Why Stream.pipeline 通过流我们可以将一大块数据拆分为一小部分一点一点的流动起来&#xff0c;而无需一次性全部读入&#xff0c;在 Linux 下我们可以通过 | 符号实现&#xff0c;类似的在 Nodejs 的 Stream 模块中同样也为我们提供了 pipe() 方法来实现。 未使用 Stream p…

Java开发安全之:Unreleased Resource: Streams需确保流得到释放

Overview java 中的函数 getResponseBytes() 有时无法成功释放由 getInputStream() 函数分配的系统资源。 Details 程序可能无法成功释放某一项系统资源。 在这种情况下&#xff0c;在某些程序路径上&#xff0c;所分配的资源未释放。 资源泄露至少有两种常见的原因&#xf…

Pyro —— Understanding how pyro works

目录 Simulation fields Inside the Pyro Solver Colliders Pressure projection Simulation fields Pyro是纯体积流体解算器&#xff0c;表示流体状态的数据存于各种标量场和矢量场&#xff1b;Smoke Object会创建这些场&#xff0c;且能可视化这些场&#xff1b; vel场&…

【JavaEE】网络原理:网络中的一些基本概念

目录 1. 网络通信基础 1.1 IP地址 1.2 端口号 1.3 认识协议 1.4 五元组 1.5 协议分层 什么是协议分层 分层的作用 OSI七层模型 TCP/IP五层&#xff08;或四层&#xff09;模型 网络设备所在分层 网络分层对应 封装和分用 1. 网络通信基础 1.1 IP地址 概念:IP地址…

Java设计模式之工厂方法模式详解

Java设计模式之工厂方法模式详解 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;在今天的篇章中&#xff0c;我们将深入探讨Java设计模式中的一种魔法&#xff0c;那…

C语言/c++指针详细讲解【超详细】【由浅入深】

指针用法简单介绍 指针&#xff0c;是内存单元的编号。 内存条分好多好多小单元&#xff0c;一个小单元有 8 位&#xff0c;可以存放 8 个 0 或 1&#xff1b;也就是说&#xff0c;内存的编号不是以位算的&#xff0c;而是以字节算的&#xff0c;不是一个 0 或 1 是一个编号&…

函数 - JS

基本语法 function 关键字&#xff1b;函数名&#xff0c;应简明扼要且具有描述性&#xff0c;没有函数名就是匿名函数&#xff1b;参数列表&#xff0c;个数≥0&#xff0c;小括号不能省略&#xff1b;函数体。 /* 基本语法 */ function 函数名(参数) { 函数体 }声明与调用 …

立体视觉几何(一)

1.什么是立体视觉几何 立体视觉对应重建&#xff1a; • 对应&#xff1a;给定一幅图像中的点pl&#xff0c;找到另一幅图像中的对应点pr。 • 重建&#xff1a;给定对应关系(pl, pr)&#xff0c;计算空间中相应点的3D 坐标P。 立体视觉&#xff1a;从图像中的投影恢复场景中点…

list下

文章目录 注意&#xff1a;const迭代器怎么写&#xff1f;运用场合&#xff1f; inserterase析构函数赋值和拷贝构造区别&#xff1f;拷贝构造不能写那个swap,为什么&#xff1f;拷贝构造代码 面试问题什么是迭代器失效&#xff1f;vector、list的区别&#xff1f; 完整代码 注…

React16源码: React中的reconcileChildIterator和reconcileChildrenArray的源码实现

reconcileChildIterator 和 reconcileChildrenArray 1 &#xff09;概述 在react更新某一个节点的时候&#xff0c;要根据这个节点&#xff0c;它的类型去获取它的children比如说如果是 Function Component&#xff0c;它要调用这个 component 计算出它的return的属性return的…

qt学习:QT对话框+颜色+文件+字体+输入

目录 概述 继承图 QColorDialog 颜色对话框 QFileDialog 文件对话框 保存文件对话框 QFontDialog 字体对话框 QInputDialog 输入对话框 概述 对于对话框的功能&#xff0c;在GUI图形界面开发过程&#xff0c;使用是非常多&#xff0c;那么Qt也提供了丰富的对话框类QDia…

网络:FTP

1. FTP 文件传输协议&#xff0c;FTP是用来传输文件的协议。使用FTP实现远程文件传输的同时&#xff0c;还可以保证数据传输的可靠性和高效性。 2. 特点 明文传输。 作用&#xff1a;可以从服务器上下载文件&#xff0c;或将本地文件上传到服务器。 3. FTP原理 FTP有控制层面…

坦克大战游戏代码

坦克大战游戏 主函数战场面板开始界面坦克父类敌方坦克我方坦克子弹爆炸效果数据存盘及恢复图片 主函数 package cn.wenxiao.release9;import java.awt.event.ActionEvent; import java.awt.event.ActionListener;import javax.swing.JFrame; import javax.swing.JMenu; impor…

RS-485通讯

RS-485通讯协议简介 与CAN类似&#xff0c;RS-485是一种工业控制环境中常用的通讯协议&#xff0c;它具有抗干扰能力强、传输距离远的特点。RS-485通讯协议由RS-232协议改进而来&#xff0c;协议层不变&#xff0c;只是改进了物理层&#xff0c;因而保留了串口通讯协议应用简单…