数据结构:哈希表 | C++中的set与map
上回说到,红黑树是提升了动态数据集中频繁插入或删除操作的性能。而哈希表(Hash Table),则是解决了传统数组或链表查找数据必须要遍历的缺点。
哈希表
哈希表的特点就是能够让数据通过哈希函数存到表中,哈希函数能够将数据处理为表中位置的索引(这个就叫映射),然后将其存入。这样一来,我们查找数据的时候只要一通过哈希函数就可以得到该数据的索引,然后进行操作。
哈希函数有很多种实现方法。
1、直接定址法
数据本身就直接作为哈希地址(即位置索引)然后进行存放,好处就是不会产生哈希冲突。
可以看到我们的存入的数据是分散在表中的,只有3个数却占用了6个位置。这也是为什么哈希表又叫散列表。这种方法只适合数据集中的情况。
2、除留余数法
这是最经典的方法。通过指定一个除数,将我们的数据进行相除来得到哈希地址。
这种方法可以有效地减少空间浪费,将数据集中起来。但是如果像2、22这样的数就会产生哈希冲突。其解决方法之后会讲到。
3、平方取中法
这个通过将数据平方计算后,根据哈希表的大小取中间的几位数,这样更有机会让数据随机均匀分布在哈希表中。
如1234的平方为1522756,哈希表的大小是100,那么去中间3位,存入227的地址中。
现在谈谈如何解决哈希冲突,一般有两种方法。
1、开放寻址法(闲散列)
顾名思义就是让空地址向发生冲突的新数据开放,让其存进去。比如线性探测和二次探测。线性探测是指按照顺序将新数据排在原本哈希地址的后面,先+1,不行+2,依次类推。而二次探测就是把这些数进行了平方再加,向前后两方进行。
那我们如果一直发生冲突,导致哈希表大小不够用了怎么办?这里需要引入“负载因子”的概念。负载因子是一个比例,表示当哈希表中的数据比哈希表的大小超过负载因子时,哈希表需要扩容,一般为0.7。
2、链地址法(开散列)
哈希桶法,拉链法一般都是指这个。
就是把每个位置作为一个链表的头,如果发生冲突,就将其作为后继节点连接在该位置下面。
虽然这样的负载因子可以大于一(即不用扩容),但因为要存储指针,会造成更多的空间开销。
我们讨论哈希表时常常会谈到“键值对”。这里的“键 Key”就是钥匙的意思,可以通过键来获取哈希地址。所以我们上文所操作的所有数据,都可以叫做键,关键码值常常也说的是这个。而另一个“值 Value”指的是与键关联的数据,其存在真正赋予了哈希表以灵活性与实用性,因为键一旦在哈希表中确认就不便更改了,而值可以随便的更新删除。所以键更像成为了值的索引,从而适应常用的操作。
之前上文中介绍的都是值为空、只有键的情况,这可以称为是哈希表实现的“集合 Set”,而包含键值对的情况称为哈希表实现的“映射 Map”。
上文提到的哈希桶,就是指储存了键值对的一个位置。“哈希桶法”就是因为一个桶下面连着挂着好几个桶而得名的。
C++中的set与map
现在终于到了追本溯源的时候了。C++的STL库中,分别有着用红黑树实现的<set><map>,还有着用哈希表实现的<unordered_set><unordered_map>,这两种结构下最显著的区别就是其有序性了,红黑树默认是升序排列的。
上次讲到红黑树的查找删除操作时间复杂度都是O(logn),而哈希表是O(1)(平均复杂度,最坏情况O(n),持续哈希冲突),可以说是这种结构最大的优势了,但其需要预分派桶数组,拉链法还有存新链表,造成更多的空间占用。那么<unordered_set>和<unordered_map>大多会用在不关心顺序,追求快速操作的场景,其他情况都用<set><map>即可。
除了STL容器的通用方法以外,集合和映射还有这些用法。
//集合
set<int> s1 = { 1, 3, 2 };
unordered_set<int> s2 = { 1, 3, 2 };
s1.count(1);//在set中由于不重复性,可用于检测存在否
s2.count(1);//返回0或1
//对于有序的set
cout << *s1.lower_bound(1) << endl;//找到大于等于目标值的数迭代器
cout << *s1.upper_bound(1) << endl;//找到大于目标值的数迭代器
//对于无序的unordered_set
int num = s2.bucket_count();//桶的数量
cout << num << endl;
cout << s2.load_factor() << endl;//查看负载因子
s2.rehash(11);//设置桶的数量,重哈希,这个过程也包含对照负载因子扩容
num = s2.bucket_count();
cout << num << endl;
//映射
map<int, int> m1 = { {1, 3}, {2, 9}, {3, 4} };//前为key后为value
unordered_map<int, int> m2 = { {1, 3}, {2, 9}, {3, 4} };
m1.count(1);//检测存在否
m2.count(1);
//插入键值对,若键已存在则不覆盖
m1.emplace(2, 1);
m2.emplace(2, 1);
m1.insert({ 4, 6 });//这个返回迭代器
m2.insert({ 4, 6 });
//通过[key]访问value
cout << m1[1] << endl;
cout << m2[4] << endl;
//对于有序的map //用first和second访问key和value
cout << m1.lower_bound(1)->first << endl;//找到key大于等于目标值的数迭代器
cout << m1.upper_bound(1)->second << endl;//找到key大于目标值的数迭代器
//对于无序的unordered_map
cout << m2.bucket(3) << endl;//返回key3的桶编号
m2.reserve(10);//预分配空间
正好,一道名为“数组的度”的题就是用哈希表解决的,就在这里练练手吧!
int findShortestSubArray(vector<int>& nums) {//key用来记录对应的数,vector用来记录索引unordered_map<int, vector<int>> m; //第一次记录for(int i = 0; i < nums.size(); i++){if(!m.count(nums[i])){ //分别是 出现次数、头索引、尾索引m[nums[i]] = {1, i, i};}else{ //增加次数,更新尾索引m[nums[i]][0]++;m[nums[i]][2] = i;}}//寻找出现次数最大的int num = 0, minLength = 0;//注意,获取的每一个是键值对类型pair<T1, T2>for(pair<int, vector<int>> it : m){if(num < it.second[0]){ num = it.second[0]; minLength = it.second[2] - it.second[1] + 1; }else if(num == it.second[0]){ if(minLength > it.second[2] - it.second[1] + 1){ minLength = it.second[2] - it.second[1] + 1;}}}return minLength;}
小结
最近笔者还真抽不出时间好好学习游戏开发有关的知识,七七八八的事情挺多。不过瓜熟蒂落,水到渠成,把事情都梳理顺畅,再着手沉淀也不晚。
如有补充纠正欢迎留言。
相关文章:
数据结构:哈希表 | C++中的set与map
上回说到,红黑树是提升了动态数据集中频繁插入或删除操作的性能。而哈希表(Hash Table),则是解决了传统数组或链表查找数据必须要遍历的缺点。 哈希表 哈希表的特点就是能够让数据通过哈希函数存到表中,哈希函数能够将数据处理为表中位置的索…...
【unity游戏开发——Animator动画】Animator动画状态机复用——重写动画控制器 Animator Override Controller
注意:考虑到UGUI的内容比较多,我将UGUI的内容分开,并全部整合放在【unity游戏开发——Animator动画】专栏里,感兴趣的小伙伴可以前往逐一查看学习。 文章目录 一、状态机复用是什么?二、实战专栏推荐完结 一、状态机复…...
第九届 蓝桥杯 嵌入式 省赛
一、分析 1. LCD 显示 显示 存储位置、定时时间和当前状态存储位置:5个,来存储定时时间当前状态 定时器停止,Standby设置时间,Setting定时器运行,Runing定时器暂停,Pause 伪代码 LCD 显示 # 显示存储位…...
电流互感器的两相星形接线的建模与仿真
微♥“电击小子程高兴的MATLAB小屋”获取巨额优惠 1.模型简介 本仿真模型基于MATLAB/Simulink(版本MATLAB 2016Rb)软件。建议采用matlab2016 Rb及以上版本打开。(若需要其他版本可联系代为转换) 2.仿真模型 3.仿真结果 3.1一次…...
【征程 6】工具链 VP 示例中 Cmakelists 解读
1. 引言 在文章【征程 6】VP 简介与单算子实操中,介绍了 VP 是什么,并以单算子 rotate 为例,介绍了 VP API 使用方法。在【征程 6】工具链 VP 示例中日志打印解读 中介绍了 VP 单算子示例中用到的日志打印的头文件应该怎么写。接下来和大家一…...
制作像素风《饥荒》类游戏的整体蓝图和流程
游戏的制作过程和核心要素拆解成以下几个主要部分: 1. 核心概念与玩法设计 (蓝图构思) 游戏类型: 确定是纯粹的生存、带有冒险元素,还是有其他侧重?(比如更强的战斗、建造或剧情)核心循环: 玩家主要做什么࿱…...
Day22 -php开发01--留言板+知识点(超全局变量 文件包含 数据库操作 第三方插件)
环境要求:php7.0.9 小皮 navicat phpstorm24.1 知识点:会写(留言板 留言板后台) 超全局变量 三方插件的使用 文件包含 1、开启小皮并利用navicat新建一个数据库 注意:本地的服务mysql关闭后 才可打开小皮。属…...
履带小车+六轴机械臂(1)
基于单片机的可移动抓取机械手 采用的是一个履带底盘和六轴机械臂做的 已经实现的功能有:PS2手柄控制六个轴的舵机转动和控制两个直流减速电机的转动,以此来达到控制移动和抓取的目地,以及用手机APP连接蓝牙模块HC-05也能达到六个轴的舵机转…...
AI:深度学习之循环神经网络(RNN)
🔄 从零入门循环神经网络(RNN):原理详解+代码实战+未来展望 🚀 摘要:在人工智能蓬勃发展的当下,循环神经网络(Recurrent Neural Network, RNN)是处理序列数据的“记忆大师”🧠,正发挥着举足轻重的作用。从自然语言处理中的文本生成、机器翻译,到语音识别、时间…...
03-libVLC的视频播放器:控制(播放/暂停/停止/拖动条/声音)
libvlc_media_player_get_state(m_pMediaPlayer) 功能:获取当前媒体播放器的状态,返回值为libvlc_state_t枚举类型。常见状态值:libvlc_Playing:正在播放libvlc_Paused:已暂停libvlc_Stopped:已停止libvlc_Ended:播放结束libvlc_Error:发生错误注意事项:状态检测是异步…...
Python_仓库使用货拉拉物流运费计算1
仓库地址为广州 物料表里有各SKU的尺寸,长宽高 货拉拉收费明细表 根据订单的SKU的数量、尺寸、重量,去寻找最合适的货拉拉车型,并计算它所需的路费 import pandas as pd# 读取数据 df_111 pd.read_excel(订单明细表.xlsx) df_material …...
CATIA高效工作指南——常规配置篇(一)
一、CATIA无窗口启动优化 原理与实现 通过修改环境变量或启动参数,可禁用启动界面以提升加载速度。添加环境变量CATNOSTARTDOCUMENT1可跳过初始画面 进阶应用: 结合脚本实现静默启动:创建批处理文件(.bat)包含start …...
【AI提示词】金融信息抽取工程师工作流程
提示说明 专注于从金融行业的文本中提取关键信息,确保准确性和规范性。具备良好的文本处理能力和数据整理经验,能够处理复杂的信息结构。 提示词 # Role:金融信息抽取工程师## Background: 用户希望从金融行业的文本中严格提取…...
8、HTTPD服务--http协议介绍
目录 一、http协议 二、web服务 1、类型 2、cookie、session 三、HTTP协议特性 1、http/0.9 2、http/1.0 3、http/1.1 4、http/2 四、HTTP状态码、请求方法 1、状态码 2、请求方法 一、http协议 应用层协议作用 在客户端、web服务器传递数据 Hyper Text Transfer …...
React useEffect
在发送请求后执行代码 useEffect(副作用函数,依赖项数组) import { useEffect, useState } from "react";const URL http://geek.itheima.net/v1_0/channels function App() {// 创建状态数据const [list,setList] useState([])const [count,setCount] …...
部署Fish-Speech实现声音克隆及文本转语音
FishSpeech 是由Fish Audio团队开发的一款开源文本转语音(TTS)模型,支持多语言的语音合成和识别。它采用先进的深度学习技术,能够生成自然流畅的语音,并提供高质量的语音转文字功能。FishSpeech 支持声音克隆ÿ…...
Qt之OpenGL中的shader layout
layout一共有两种绑定方法。一种是把设定好的值绑定到shader中、另一种是shader中的layout绑定到代码中。 第一种方法(注意:要在link之前绑定同时要把shader代码中的layout设置删掉) void sunOpengl::initializeGL() {this->initializeO…...
【问题记录】记录2个安装Centos/Anolis系统卡死在安装包阶段的问题?(硬盘分区?换设备)
背景 问题就不详细记录了,本文记录的是Centos/Anolis安装中卡主的问题。这个问题遇到过几十次了,尝试过各种方法。最近一个偶然因素找到了原因。然后翻看历史上出现这个问题的照片居然是相同的地方卡死。。。 有点意思。特此记录,希望未来遇…...
用纯Qt实现GB28181协议/实时视频/云台控制/预置位/录像回放和下载/事件订阅/语音对讲
一、前言 在技术的长河中探索,有些目标一旦确立,便如同璀璨星辰,指引着我们不断前行。早在2014年,我心中就种下了用纯Qt实现GB28181协议的种子,如今回首,一晃十年已逝,好在整体框架和逻辑终于打…...
论文阅读笔记——Multi-Token Attention
MTA 论文 在 Transformer 中计算注意力权重时,仅依赖单个 Q 和 K 的相似度,无法有效捕捉多标记组合信息。(对于 A、B 两个词,单标记注意力需要分别计算两个词的注意力分数,再通过后处理定位共同出现的位置或通过多层隐…...
【VitePress】新增md文件后自动更新侧边栏导航
目录 说在前面先看效果代码结构详细说明侧边栏格式utils监听文件变化使用pm2管理监听进程 说在前面 操作系统:windows11node版本:v18.19.0npm版本:10.2.3vitepress版本:1.6.3完整代码:github 先看效果 模板用的就是官…...
redis大key排查指南
文章目录 一、什么是 Redis 大 Key?二、为什么要排查大 Key?三、如何排查 Redis 大 Key?1、使用 Redis 自带的命令 bigkeys2、使用 SCAN MEMORY USAGE Redis 基本数据数据类型String(字符串)Hash(哈希&…...
Rasa总体目录架构介绍
详细讲解一下每个主要文件/目录的作用,以及之后如何一步步使用它们来训练和运行你的聊天机器人。 📁 Rasa 项目结构说明(初始化后生成的主要文件) . ├── actions/ │ └── actions.py # 自定义 action 的地方&…...
Python functools模块:函数式编程工具的探索之旅
Python functools模块:函数式编程工具的探索之旅 起源 那是天空线科技公司的一个阴雨绵绵的周二,我首次遇到了一个彻底改变我编程方式的问题。我们团队接到任务,需要优化一个日益复杂且难以维护的关键数据处理流水线。当时的代码库就像一张蜘蛛网,充斥着嵌套函数、重复计…...
吴恩达深度学习复盘(14)迁移学习|项目基本周期
迁移学习 迁移学习是一种机器学习技术,它允许我们将从一个任务中学习到的知识应用到另一个相关的任务中。其核心思想在于,很多情况下,从头开始训练一个模型需要大量的数据和计算资源,而迁移学习能够复用在已有数据上训练好的模型…...
[福游宝——AI智能旅游信息查询平台]全栈AI项目-阶段一:Vite前端开荒
简言 本项目旨在构建一个以AI智能体为核心的福建省旅游信息查询系统,聚焦景点推荐、路线规划、交通天气查询等功能,为游客提供智能化、便捷化的旅游信息服务。项目采用前后端分离架构,前端基于Vite TypeScript Vue3技术栈,搭配…...
SpringCloud-OpenFeign
前言 1.存在问题 远程调用可以像Autowired一样吗 服务之间的通信⽅式,通常有两种:RPC和HTTP. 在SpringCloud中,默认是使⽤HTTP来进⾏微服务的通信,最常⽤的实现形式有两种: RestTemplate OpenFeign RPC(RemoteProcedureCall)远程过程调⽤&…...
程序化广告行业(79/89):技术革新与行业发展脉络梳理
程序化广告行业(79/89):技术革新与行业发展脉络梳理 大家好!一直以来,我都热衷于在技术领域不断探索,也深知知识共享对于进步的重要性。写这篇博客,就是希望能和大家一起深入研究程序化广告行业…...
[算法题:快排(一)]颜色分类
1->题目链接 算法题:颜色分类 2->题目解析 数字0表示红色,数字1表示白色,数字2表示蓝色. 这到题说白了就是让我们进行排序,数组中只会有 0 1 2 三种数字 3->算法原理 类⽐数组分两块的算法思想,这⾥是将数组分成三块,那么我们可以再添加⼀个…...
论文精度:YOLOMG:基于视觉的无人机间检测算法——外观与像素级运动融合详解
论文地址:https://arxiv.org/pdf/2503.07115 1. 论文概述 论文标题:YOLOMG: Vision-based Drone-to-Drone Detection with Appearance and Pixel-Level Motion Fusion 作者:Hanqing Guo, Xiuxiu Lin, Shiyu Zhao 发表:未明确会议/期刊(推测为预印本或待发表) 核心贡献:…...
Redis:线程模型
单线程模型 Redis 自诞生以来,一直以高性能著称。很多人好奇,Redis 为什么早期采用单线程模型,它真的比多线程还快吗? 其实,Redis 的“快”并不在于并发线程,而在于其整体架构设计极致简单高效,…...
C++进阶——C++11_{ }初始化_lambda_包装器
目录 1、{ }初始化 1.1 C98的{ } 1.2 C11的{ } 1.3 C11中的std::initializer_list 总结一下: 2、lambda 2.1 lambda的语法 2.2 捕捉列表 2.3 lambda的应用 2.4 lambda的原理 3、包装器 3.1 function 3.2 bind 1、{ }初始化 1.1 C98的{ } C98中一般数组…...
十大PDF解析工具在不同文档类别中的比较研究
PDF解析对于包括文档分类、信息提取和检索在内的多种自然语言处理任务至关重要,尤其是RAG的背景下。尽管存在各种PDF解析工具,但它们在不同文档类型中的有效性仍缺乏充分研究,尤其是超出学术文档范畴。通过使用DocLayNet数据集,比…...
【LeetCode Solutions】LeetCode 160 ~ 165 题解
CONTENTS LeetCode 160. 相交链表(简单)LeetCode 162. 寻找峰值(中等)LeetCode 164. 最大间距(中等)LeetCode 165. 比较版本号(中等) LeetCode 160. 相交链表(简单&#…...
关于 Spring Boot 微服务解决方案的对比,并以 Spring Cloud Alibaba 为例,详细说明其核心组件的使用方式、配置及代码示例
以下是关于 Spring Boot 微服务解决方案的对比,并以 Spring Cloud Alibaba 为例,详细说明其核心组件的使用方式、配置及代码示例: 关于 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案! https://sca.aliyun.com/?spm7145af80…...
3.1多状态专题:LeetCode面试题17.16 按摩师
动态规划解决按摩师预约问题——以LeetCode面试题17.16为例 1.题目链接 LeetCode面试题17.16 按摩师 2.题目描述 一个有名的按摩师收到一系列的预约请求,每个预约都可以选择接受或不接受。但相邻的预约不能同时接受。给定一个包含各预约时长的数组 nums…...
Netty基础入门(一)
1.EventLoopGroup 1、概念 EventLoopGroup 是一组 EventLoop,Channel 一般会调用 EventLoopGroup 的 register 方法来绑定其中一个 EventLoop,后续这个 Channel 上的 io 事件都由此 EventLoop 来处理(保证了 io 事件处理时的线程安全&#x…...
Transformer模型的自注意机制原理、作用、优缺点,通俗易懂
Transformer模型中的自注意力机制(Self - attention Mechanism)可以通俗地理解为一种让模型自动关注文本中不同部分之间关系的方法。 工作原理 假设你有一句话“我正在吃苹果”,自注意力机制会让模型去分析每个词和其他词之间的关联程度。比…...
设计模式-结构型模式-代理模式
概述 代理模式: Proxy Pattern : 是一种结构型设计模式. 它允许你提供一个替代对象来代表真实对象,以此控制对真实对象的访问。 通过代理对象,可以在不改变目标对象的前提下,扩展其功能或控制对其的访问。 简单理解 : 代理模式就是…...
大模型开发:源码分析 Qwen 2.5-VL 视频抽帧模块(附加FFmpeg 性能对比测试)
目录 qwen 视频理解能力 messages 构建 demo qwen 抽帧代码分析 验证两个实际 case 官网介绍图 性能对比:ffmpeg 抽帧、decord 库抽帧 介绍 联系 对比 测试结果 测试明细 ffmpeg 100 qps 测试(CPU) decord 100 qps 测试&#x…...
单调栈 —— 1.基本概念与核心算法
1. 基本概念 1.1 知识预备 在理解单调栈之前,我们需要先掌握两个基础概念:栈(Stack) 和 单调性(Monotonicity)。 什么是栈(Stack) 栈是一种**后进先出(LIFO, Last-In…...
Ollama部署大模型 (完整版本、网速慢处理、聊天界面)
切记!切记!切记! Ollama软件下载的模型一般都是别人微调好的,且模型文件与HuggingFace等平台不一样,使用为主,没有官方API可以对模型微调(教程都是cpp这类的,没必要这么麻烦去操作&a…...
CMake中add_custom_command用法详解
add_custom_command 是 CMake 中用于在构建过程中添加自定义命令的工具。它通常用于生成文件或在构建特定目标前后执行操作。其行为和执行时机取决于具体使用场景。 主要用法 add_custom_command 有两种典型用法: 1. 生成文件(Generating Files&#x…...
基于疾风大模型的新能源储能优化系统:方法、实现与案例分析
一、引言 随着可再生能源渗透率不断提高,储能系统在电力系统中的重要性日益凸显。传统储能控制方法主要基于规则策略和简单优化算法,难以应对高比例新能源场景下的复杂决策需求。本文将详细介绍如何利用疾风大模型(Gale Model)构建智能化的新能源储能优化系统,包含核心方…...
Large Language Model(LLM)的训练和微调
之前一个偏工程向的论文中了,但是当时对工程理论其实不算很了解,就来了解一下 工程流程 横轴叫智能追寻 竖轴上下文优化 Prompt不行的情况下加shot(提示),如果每次都要加提示,就可以试试知识库增强检索来给提示。 如果希望增强…...
Windows 系统中安装 Git 并配置 GitHub 账户
由于电脑重装系统,重新配置了git. 以下是在 Windows 系统中安装 Git 并配置 GitHub 账户的详细步骤: 1. 安装 Git 访问 Git 官网下载页面下载 Windows 版本的 Git 安装程序运行安装程序,使用默认选项即可 2. 配置 Git 用户信息 打开命令…...
KWDB创作者计划—KWDB场景化创新实践:多模态数据融合与边缘智能的突破性应用
引言:AIoT时代的数据库范式重构 在工业物联网设备数量突破千亿、边缘计算节点覆盖率达75%的2025年,传统数据库面临多模态数据处理效率低下、边缘端算力利用率不足、跨域数据协同困难等核心挑战。KWDB(KaiwuDB Community Edition)通…...
波束形成(BF)从算法仿真到工程源码实现-第四节-最小方差无失真响应波束形成(MVDR)
一、概述 本节我们讨论最 小 方 差 无 失 真 响 应 (Minimum Variance Distortionless Response, MVDR)波束形成算法,包括原理分析及代码实现。 更多资料和代码可以进入https://t.zsxq.com/qgmoN ,同时欢迎大家提出宝贵的建议,以共同探讨学习…...
初阶数据结构--链式二叉树
二叉树(链式结构) 前面的文章首先介绍了树的相关概念,阐述了树的存储结构是分为顺序结构和链式结构。其中顺序结构存储的方式叫做堆,并且对堆这个数据结构进行了模拟实现,并进行了相关拓展,接下来会针对链…...
嵌入式硬件篇---单片机周期
文章目录 前言 前言 在单片机中,时序控制是其执行指令和协调外设的核心基础。以下是单片机中常见的各种周期及其详细说明,以层次结构展开: 时钟周期(Clock Cycle) 定义: 时钟周期是单片机的最小时间单位&a…...