C++中的unordered_set和unordered_map的模拟实现
一、封装基本结构
与map和set的封装过程很想,unordered_set和unordered_map也需要用MapKeyOfT和SetKeyOfT创建哈希表类型,借此获取对应的key值来使用;
因此,在哈希表中也一样需要用参数class T来替代set中的key和map中的pair<key,value>
二、迭代器的实现
2.1普通迭代器及其问题
如map和set中一样,迭代器中也需要存储一个节点的指针,整体结构类似

但若是只存储一个节点的指针,在实现operator++的过程中会遇到一个问题:
如果迭代器此时指向“10”这个节点,应该如何找到它的下一个节点呢?
只存结点的话,会导致此时不知表的存在,这个问题是无解的。
因此需要让迭代器中有表的信息,有了表的情况后即可通过计算的出当前映射位置,进而找到下一个非空的映射位置
解决:通过传入迭代器中指针数组或者整个哈希表,而这两者之中,更方便的是传入哈希表
自此我们的迭代器类中的成员变量设置为
Node* _node;
const HashTable<K, T, KeyOfT, Hash>* _pht;
其余* 和->的重载以及begin和end的封装过程与map和set中思路相同,在实现逻辑方面:
begin要去找第一个非空映射位置
end要去构造空迭代器
2.1补:在迭代器中传入哈希表会导致两个问题
①在之前要有哈希表的定义;而在哈希表中因为要对迭代器进行typedef,所以在哈希表定义之前也要有迭代器的定义
可以通过将后定义的声明移到先定义的之前
②在++的逻辑中,我们需要访问私有成员_tables(即哈希表中的指针数组),会出现权限问题
其一,可以通过在哈希表中实现一个get函数来获取私有成员变量
其二,可以设置迭代器类为哈希表的友元类
template<class K, class T, class KeyOfT, class Ref, class Ptr, class Hash>
friend struct HSIterator;
2.2const迭代器
整体的逻辑与set和map封装中一样,但是会出现一个权限方面的问题:
因为之前在迭代器中传入了一个哈希表作为成员变量,所以构造函数的实现中也会出现
HSIterator(Node* node,HashTable<K, T, KeyOfT, Hash>* pht)
{}
而对应begin中我们进行构造迭代器时传值也是直接传入this指针,
但轮到Constbegin的实现,我们需要使用const来修饰成员函数(Constbegin是在哈希表类中实现的)
ConstIterator Begin() const
{}
我们要注意,const修饰成员函数的时候,this指针会被const修饰
此时我们
ConstIterator(_tables[hashi], this)
的第二个参数实际上传入的是
const HashTable<K, T, KeyOfT, Hash>*
综上所述:
传入的是const修饰的类型,但是参数列表中确实普通的类型,会导致权限放大的问题
为了解决这一冲突,遵顼权限可以缩小但是不可以放大的原则,我们需要在参数列表中加const修饰,此时参数列表变为
HSIterator(Node* node,const HashTable<K, T, KeyOfT, Hash>* pht)
{}
2.3普通迭代器也不应该允许修改
对于unordered_set来说,若是允许随意修改key的值会导致映射位置错乱,影响后续的查找操作
为了实现这一要求,我们可以在设置unordered_set的成员变量的时候设为
HashTable<K, const K, SetKeyOfT,Hash> _hs;
而对于unordered_map来说也是同理,只是value的值应该可以随意修改,所以其成员变量可以设置为
HashTable<K, pair<const K, V>, MapKeyOfT,Hash> _hs;
三、其他功能的实现
3.1Insert,Find,Erase的实现
如set和map中一样,主要逻辑在哈希表中实现,而unordered_set和unordered_map中只要套一层壳调用即可
3.2operator[]的实现
这是unordered_map特有的,要在对应类中单独实现,思路与map中完全一致
3.3让unordered_set和unordered_map支持自定义类型的映射
底层为哈希表,那么传入自定义类型的时候无法转换为size_t就是一个需要解决的问题
因为日常使用nordered_set和unordered_map是无法直接为哈希表的模板参数传参的,所以我们需要把哈希函数上移一层到unordered_set和unordered_map中,如
四、库中关于unordered_set和unordered_map的其他接口
4.1统计当前桶的总数
size_type bucket_count() const noexcept;
4.2获取第n个桶的长度
size_type bucket_size ( size_type n ) const;
4.3获取当前负载因子
float load_factor() const noexcept;
4.4设置桶的数量
void reserve ( size_type n );
4.5unordered_set和unordered_map使用的其他问题
①要计算平均桶的长度,我们只算有数据的桶才有意义,否则就是算负载因子大小
②如果已知数据量,可以提前reserve桶的数量,如链表中一样,哈希表增加桶的过程会产生不小的消耗
相关文章:
C++中的unordered_set和unordered_map的模拟实现
一、封装基本结构 与map和set的封装过程很想,unordered_set和unordered_map也需要用MapKeyOfT和SetKeyOfT创建哈希表类型,借此获取对应的key值来使用; 因此,在哈希表中也一样需要用参数class T来替代set中的key和map中的pair<…...
Spring Boot 2 学习指南与资料分享
Spring Boot 2 学习资料 Spring Boot 2 学习资料 Spring Boot 2 学习资料 在当今竞争激烈的 Java 后端开发领域,Spring Boot 2 凭借其卓越的特性,为开发者们开辟了一条高效、便捷的开发之路。如果你渴望深入学习 Spring Boot 2,以下这份精心…...
(一)QSQLite3库简介
1、SQLite数据库 SQLite数据库,作为一个轻量级的关系型数据库管理系统,广泛应用于移动设备和桌面应用程序中。由于其简单易用、无需配置的特点,它为开发者提供了极大的便利。然而,正是由于其应用广泛,随着用户对于系统…...
《计算机网络》课后探研题书面报告_网际校验和算法
网际校验和算法 摘 要 本文旨在研究和实现网际校验和(Internet Checksum)算法。通过阅读《RFC 1071》文档理解该算法的工作原理,并使用编程语言实现网际校验和的计算过程。本项目将对不同类型的网络报文(包括ICMP、TCP、UDP等&a…...
hot100_240. 搜索二维矩阵 II
hot100_240. 搜索二维矩阵 II 直接遍历列减行增 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。 每列的元素从上到下升序排列。 示例 1: 输入:matrix [[1,4,7,1…...
78_Redis网络模型
1.Redis网络模型概述 1.1 Redis网络模型介绍 Redis 7.x的网络模型基于epoll的Reactor模式实现,这是一个高效的事件驱动模型。在Redis中,所有的网络事件(如连接、读写等)都由一个事件循环(Event Loop)来处理。这个事件循环负责监听套接字上的事件,并根据事件类型调用相…...
python范围
用户图形界面-工资计算器 from tkinter import *def f():w int(e1.get()) int(e2.get()) - int(e3.get())wage.insert(0,w)root Tk() root.title("工资计算器") Label(root, text"每月基本工资:").pack() e1 Entry(root) e1.pack() Label(…...
vulnhub靶场【Raven系列】之2 ,对于mysql udf提权的复习
前言 靶机:Raven-2,IP地址为192.168.10.9 攻击:kali,IP地址为192.168.10.2 都采用虚拟机,网卡为桥接模式 文章所用靶机来自vulnhub,可通过官网下载,或者通过链接:https://pan.quark.cn/s/a65…...
基于vite+vue3+mapbox-gl从零搭建一个项目
下面是基于 Vite、Vue 3 和 Mapbox GL 从零搭建一个项目的完整步骤,包括环境搭建、依赖安装、配置和代码示例。 1. 初始化项目 首先,使用 Vite 快速创建一个 Vue 3 项目: npm create vuelatest vue3-mapboxgl --template vue cd vue3-mapbo…...
向harbor中上传镜像(向harbor上传image)
向 Harbor 中上传镜像通常分为以下几个步骤: 1、登录 Harbor 2、构建镜像 3、标记镜像 4、推送镜像到 Harbor 仓库 1、登录 Harbor 首先,确保你已经能够访问 Harbor,并且已经注册了账户。如果还没有 Harbor 账户,你需要先注册一…...
【线性代数】行列式的性质
行列式性质定理讲义 一、行列式的基本性质 性质 1:行列互换 对于任意一个 n n n \times n nn 的方阵 A A A,其行列式 ∣ A ∣ |A| ∣A∣ 满足: ∣ A ∣ ∣ A T ∣ |A| |A^T| ∣A∣∣AT∣ 其中, A T A^T AT 是 A A A 的…...
智能家居企业如何通过设计师渠道打造第二曲线?
随着智能家居行业的迅速发展和消费者需求的不断升级,企业的营销策略也在不断变化。传统的B2C营销模式逐渐让位于更加精细化、定制化的B2B2C模式,其中设计师渠道的开发与合作,成为智能家居企业布局市场、提升品牌影响力的关键。 智能家居推广的…...
Unity3d 实时天气系统基于UniStorm插件和xx天气API实现(含源码)
前言 实时天气在Unity3d三维数字沙盘中的作用非常重要,它能够增强虚拟环境的真实感和互动性,实时天气数据的应用可以提供更为精准和直观的天气信息支持,如果真实的数据加上特效、声音和模型反馈会提高产品档次,提高真实感。 目前…...
年后找工作需要注意的事项
大家好!我是 [数擎 AI],一位热爱探索新技术的前端开发者,在这里分享前端和 Web3D、AI 技术的干货与实战经验。如果你对技术有热情,欢迎关注我的文章,我们一起成长、进步! 开发领域:前端开发 | A…...
模拟器多开窗口单IP与代理IP关系
模拟器多开窗口同IP背后出现的问题 在游戏世界中,模拟器多开窗口是玩家们提升体验的常见做法。通过在同一设备上开启多个模拟器窗口,玩家可以同时运营多个游戏账号,增加游戏的趣味性和效率。 一旦检测到一个IP地址下登录了过多的账号&#x…...
Android ScrollView嵌套X5WebView大片空白问题
scrollview嵌套后webview的高度不可控。留有大片空白。 注:官方不建议scrollview嵌套webview 最好让webview自身滚动 解决方案: act_news_detail_wv.setWebViewClient(new WebViewClient() {Overridepublic void onPageFinished(WebView webView, Str…...
Java Web开发进阶——WebSocket与实时通信
WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,广泛应用于需要实时数据交换的应用程序中。它能够实现服务器与客户端之间的双向通信,避免了传统 HTTP 请求/响应的延迟。结合 Spring Boot,开发实时通信应用变得更加高效与简便。 1. …...
zerotier搭建虚拟局域网,自建planet
基于该开源项目 自建planet节点,更快速,更安全 本教程依据docker-zerotier-planet 项目文档书写,并以linux(centos 7)和windows作为示例,需要其他系统配置方法,可移步项目文档 一. 前置资源 具有外网ip的服务器 后面…...
SQL面试题1:连续登陆问题
引言 场景介绍: 许多互联网平台为了提高用户的参与度和忠诚度,会推出各种连续登录奖励机制。例如,游戏平台会给连续登录的玩家发放游戏道具、金币等奖励;学习类 APP 会为连续登录学习的用户提供积分,积分可兑换课程或…...
2Spark Core
2Spark Core 1.RDD 详解1) 为什么要有 RDD?2) RDD 是什么?3) RDD 主要属性 2.RDD-API1) RDD 的创建方式2) RDD 的算子分类3) Transformation 转换算子4) Action 动作算子 3. RDD 的持久化/缓存4. RDD 容错机制 Checkpoint5. RDD 依赖关系1) 宽窄依赖2) 为什么要设计宽窄依赖 …...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
Rust 开发环境搭建
环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu 2、Hello World fn main() { println…...
