C++手动实现一个HashMap

1.HashMap原理

参考我的博客:https://blog.csdn.net/Revendell/article/details/110009858

  • 开链法:STL的hashtable便是采用开链法解决冲突。这种做法是在每一个表格元素中维护一个list:散列函数为我们分配某一个list,然后我们在那个list身上执行元素的插入、搜寻、删除等操作。虽然针对list而进行的搜寻只能是一种线性操作,但如果list够短,速度还是够快。使用开链法,表格的负载系数将大于1(元素个数除以表格大小)。
  • 动态扩容:buckets聚合体以vector完成,以利动态扩充,vector<node*,Alloc> buckets。num_elements为hashtable中元素个数,bucket_count()返回bucket个数即buckets vector的大小。hashtable的计算元素位置赋予给了函数bkt_num(),通过它调用散列函数取得一个可以执行取模运算的值。开链法并不要求表格大小必须为质数,但STL仍然以质数来设计表格大小,并且先将28个质数计算好,逐渐呈现大约两倍的关系,以备随时访问,同时提供一个函数,用来查询在这28个质数之中最接近某数并大于某数的质数。

2.代码解析

  • 数据结构:这个实现选择使用向量和链表来处理可能出现的哈希冲突。std::vector<std::list<std::pair<K, V>>> table:底层容器是一个向量,其每个元素是一个链表,用于存储具有相同哈希值的键值对。
  • 哈希函数std::hash<K>()(key) 用于生成哈希值,这个哈希函数对许多内置类型都有定义,你也可以根据需要自定义。
  • 插入操作:在插入时,首先通过计算哈希值确定需要插入的链表。如果键已经存在,就更新其值,否则在链表尾部插入新的键值对。
  • 删除操作:删除时,找到对应的键,并将其从链表中移除。
  • 查找操作:查找时,通过哈希和链表搜索来快速找到键对应的值。如果找到了键,则返回关联的值。

3.代码实现

#include <iostream>
#include <vector>
#include <list>
#include <utility>template <typename K, typename V>
class HashMap {
public:HashMap(size_t size = 101) : table(size) {}bool insert(const K& key, const V& value) {size_t idx = hash(key) % table.size();for (auto& kv : table[idx]) {if (kv.first == key) {kv.second = value;  // 如果键已经存在,更新值return true;}}table[idx].emplace_back(key, value);return true;}bool erase(const K& key) {size_t idx = hash(key) % table.size();auto& chain = table[idx];for (auto it = chain.begin(); it != chain.end(); ++it) {if (it->first == key) {chain.erase(it);return true;}}return false;  // 未找到键}bool find(const K& key, V& value) const {size_t idx = hash(key) % table.size();const auto& chain = table[idx];for (const auto& kv : chain) {if (kv.first == key) {value = kv.second;return true;}}return false;  // 未找到键}private:std::vector<std::list<std::pair<K, V>>> table;size_t hash(const K& key) const {// 一个简单的哈希函数return std::hash<K>()(key);}
};int main() {HashMap<std::string, int> map;map.insert("apple", 3);map.insert("banana", 2);map.insert("orange", 5);int value;if (map.find("apple", value)) {std::cout << "Apple: " << value << std::endl;} else {std::cout << "Apple not found" << std::endl;}map.erase("banana");if (map.find("banana", value)) {std::cout << "Banana: " << value << std::endl;} else {std::cout << "Banana not found" << std::endl;}return 0;
}

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

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

相关文章

【Linux】深入理解进程信号机制:信号的产生、捕获与阻塞

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 时间不语&#xff0c;却回答了所有问题 目录 &#x1f4da;前言 &#x1f4da;一、信号的本质 &#x1f4d6;1.异步通信 &#x1f4d6;2.信…

sql server 数据库还原,和数据检查

右键数据库选择还原&#xff0c; 还原的备份文件必须选择在本地的文件&#xff08;远程文件没有试过&#xff09;还原数据库名字可以修改&#xff0c;然后file选择中有个2个目录data file 的目录 &#xff0c;和log data 的目录都可以重新选择还原到的新的目录&#xff0c;不要…

v31蓝牙信标方案

革新点 带蜂鸣器功能 容易安装和移动 多彩均匀明显的指示灯 长电池寿命&#xff0c;常规使用1-2年 自带1个按键 钮扣电池组供电 产品概述 电子标签拣货系统是一组安装在货架储位上的电子设备&#xff0c;通过计算机与软件的控制&#xff0c;藉由指示灯或数字显示作为辅助…

内存中优雅的csv对象(Python)

磁盘*.csv文件是文本&#xff0c;以行结构的二维list是内存中的“csv”。 (笔记模板由python脚本于2024年12月18日 10:15:23创建&#xff0c;本篇笔记适合学习过list、panda的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&…

OpenGL —— 2.6.1、绘制一个正方体并贴图渲染颜色(附源码,glfw+glad)

源码效果 C++源码 纹理图片 需下载stb_image.h这个解码图片的库,该库只有一个头文件。 具体代码: vertexShader.glsl #version

H5 中 van-popup 的使用以及题目的切换

H5 中 van-popup 的使用以及题目的切换 在移动端开发中&#xff0c;弹窗组件是一个常见的需求。vant 是一个轻量、可靠的移动端 Vue 组件库&#xff0c;其中的 van-popup 组件可以方便地实现弹窗效果。本文将介绍如何使用 van-popup 实现题目详情的弹窗展示&#xff0c;并实现…

Metaploit-永恒之蓝漏洞利用

1&#xff1a;Metaploit介绍   本次测试主要是利用永恒之蓝漏洞对windows7进行控制利用&#xff0c;掌握Metaploit工具的使用&#xff0c;知道永恒之蓝的漏洞利用原理。永恒之蓝是在Windows的SMB服务处理SMB v1请求时发生的漏洞&#xff0c;这个漏洞导致攻击者在目标系统上可…

FPGA高速下载器SZ901

SZ901基于AMD(Xilinx) Virtual Cable协议. 本设备使用千兆网络接口。基于此接口,本设备可以同时支持多达四路FPGA板卡同时调试,每组相互独立,互不干扰。 特点 1,支持JTAG 速度最高53Mb/s&#xff0c;电压范围1.2-3.3V,最高支持200cm排线 2,支持4路JTAG独立使用 3,支持多路…

【递归,搜索与回溯算法】穷举 vs 暴搜 vs 深搜 vs 回溯 vs 剪枝算法入门专题详解

前言 什么是回溯算法&#xff1f; 回溯算法是一种经典的递归算法&#xff0c;通常用于解决组合问题、排列问题和搜索问题等。 回溯算法的基本思想 从一个初始状态开始&#xff0c;按照一定的规则向前搜索&#xff0c;当搜索到某个状态无法前进时&#xff0c;回退…

设计模式之桥接模式:抽象与实现之间的分离艺术

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” 桥接模式概述与角色组成 想象一下你家里的电视遥控器&#xff0c;无论是索尼还是三星的电视机&#xff0c;遥控器的按键功能都差不多&#xff1…

ASRPRO学习笔记一之语音模型位置和语音替换

一、语音替换的步骤 1、扬声器录音 打开GoldWave,点击工具栏中的蓝色控制属性按钮&#xff0c;点击设备&#xff0c;选择扬声器&#xff0c;点击ok。打开电脑上的网易云音乐&#xff0c;点击红色的录制按钮&#xff0c;开始录制音乐&#xff0c;在网易云音乐上点击播放音乐,录…

多因子认证 (Multi-factor authentication, MFA)

多因子认证 (MFA) 是一种思想&#xff0c;而UsernamePassword&#xff0c;OTP等是具体的认证手段。多因子认证就是将这些认证手段结合。 目录 什么是MFAMFA的作用MFA的实际应用 认证认证 (Authentication, AuthN) 因素常见的认证 (Authentication, AuthN) 类型密码认证无密码认…

内存压缩禁用设置

设置禁用内存压缩功能 1、“Win”“X”键→“A”键 2、如果输入“Get-MMAgent”并按“Enter”键&#xff0c;则可以从“MemoryCompression”中检查内存压缩功能的状态。 True启用&#xff0c;False禁用 3、要禁用内存压缩功能&#xff0c;请输入“Disable-MMAgent -mc”并…

素数回文数的个数

素数回文数的个数 C语言代码C 代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 求11到n之间&#xff08;包括n&#xff09;&#xff0c;既是素数又是回文数的整数有多少个。 输入 一个大于11小于1000的整数n。 输出…

QT网络(一):主机信息查询

网络简介 在QT中进行网络通信可以使用QT提供的Qt Network模块&#xff0c;该模块提供了用于编写TCP/IP网络应用程序的各种类&#xff0c;如用于TCP通信的QTcpSocket和 QTcpServer&#xff0c;用于 UDP 通信的 QUdpSocket&#xff0c;还有用于网络承载管理的类&#xff0c;以及…

Flutter Navigator2.0的原理和Web端实践

01 背景与动机 在Navigator 2.0推出之前&#xff0c;Flutter主要通过Navigator 1.0和其提供的 API&#xff08;如push(), pop(), pushNamed()等&#xff09;来管理页面路由。然而&#xff0c;Navigator 1.0存在一些局限性&#xff0c;如难以实现复杂的页面操作&#xff08;如移…

如何在谷歌浏览器中开启安全浏览

在数字化时代&#xff0c;网络安全变得愈发重要。作为全球最受欢迎的网络浏览器之一&#xff0c;谷歌浏览器提供了多种功能来保护用户的在线安全。本文将详细介绍如何在谷歌浏览器中开启安全浏览&#xff0c;并额外提供一些有用的页面滚动设置、地址栏快捷搜索和跟踪防护的相关…

【物联网技术与应用】实验3:七彩LED灯闪烁

实验3 七彩LED灯闪烁 【实验介绍】 七彩LED灯上电后&#xff0c;7色动闪光LED模块可自动闪烁内置颜色。它可以用来制作相当吸引人的灯光效果。 【实验组件】 ● Arduino Uno主板* 1 ● USB数据线* 1 ● 7彩LED模块*1 ● 面包板*1 ● 9V方型电池*1 ● 跳线若干 【实验原…

直播美颜插件开发全流程:从美颜sdk的集成到实际部署

对于开发者来说&#xff0c;如何高效地开发和部署一个直播美颜插件&#xff0c;则需要从美颜SDK的集成到实际部署的全流程把控。本篇文章&#xff0c;我将详细解析这个流程中的关键技术和核心环节&#xff0c;助力开发者高效完成项目交付。 一、项目需求分析与技术选型 在开发…

【物联网技术与应用】实验4:继电器实验

实验4 继电器实验 【实验介绍】 继电器是一种用于响应施加的输入信号而在两个或多个点或设备之间提供连接的设备。换句话说&#xff0c;继电器提供了控制器和设备之间的隔离&#xff0c;因为设备可以在AC和DC上工作。但是&#xff0c;他们从微控制器接收信号&#xff0c;因此…