【C++】unordered系列

前言:

在C++11及以后的标准中,unordered容器是标准模板库(STL)的一部分,提供了高效的数据结构选项,适用于需要快速查找和插入操作的场景。

unordered通常与关联容器一起使用,特别是unordered_mapunordered_set。这些容器提供了基于哈希表的实现,它们提供了与map和set相似的接口,但在查找、插入和删除操作上通常具有更高的性能,尤其是在处理大量数据时。

  • unordered_map是一个关联容器,它存储键值对,并根据键的哈希值进行排序,以实现快速的查找操作。
  • unordered_set则存储唯一的元素,并使用哈希表来管理这些元素,以便快速检查一个元素是否存在于集合中。

unordered_map的接口说明

注: unordered_mapunordered_set接口相似就只介绍一个接口。

unordered_map的接口说明

函数声明功能介绍
unordered_map构造不同格式的unordered_map对象

unordered_map的容量

函数声明功能介绍
bool empty()const检测unordered_map是否为空
size_t size() const获取unordered_map的有效元素个数

unordered_map的迭代器

函数声明功能介绍
begin返回unordered_map第一个元素的迭代器
end返回unordered_map最后一个元素下一个位置的迭代器
cbegin返回unordered_map第一个元素的const迭代器
cend返回unordered_map最后一个元素下一个位置的const迭代器

unordered_map的元素访问

函数声明功能介绍
operator[]返回与key对应的value,没有一个默认值

unordered_map的查询

函数声明功能介绍
iterator find(const K& key)返回key在哈希桶中的位置
size_t count(const K& key)返回哈希桶中关键码为key的键值对的个数

unordered_map的修改操作

函数声明功能介绍
insert向容器中插入键值对
erase删除容器中的键值对
void clear()清空容器中有效元素个数
void swap(unordered_map&)交换两个容器中的元素

unordered_map的桶操作

函数声明功能介绍
size_t bucket_count()const返回哈希桶中桶的总个数
size_t bucket_size(size_t n)const返回n号桶中有效元素的总个数
size_t bucket(const K& key)返回元素key所在的桶号

哈希

  1. **哈希(Hash)**是一种将任意大小的数据映射为固定大小值的函数,通常用于数据的快速查找和存储。
  2. **哈希表(Hash Table)**是基于哈希函数的一种数据结构,它通过计算关键字的哈希值来直接访问存储位置,从而实现常数时间复杂度的查找性能。

在这里插入图片描述

  • 在这里面的经过一系列的处理,得到的结果就映射到对应的位置,方便查找,加快了查找的速度。但是也会引发一系列的问题(哈希冲突)。

哈希函数

向上面的通过一系列的计算的过程就是哈希函数,有点类似于数学上的函数,一个数经过对应关系会得到两者的映射的关系。

常见的哈希函数

  1. 直接定址法:这种方法通过一个简单的线性函数计算哈希地址,公式为 Hash(Key) = A * Key + B。这种方法简单且分布均匀,但需要提前知道键值的分布情况。
  2. 除留余数法:这是一种常用的哈希函数,通过取关键字除以一个质数后的余数作为哈希地址,公式为 Hash(Key) = Key % p,其中 p 是一个不大于哈希表大小且最接近或等于哈希表大小的质数。
  3. 乘法取余法:这种方法通过将关键字乘以一个固定的数(通常是一个接近2的数),然后取结果的整数部分并进行取模运算来计算哈希地址。这种方法适用于处理字符串等非整数类型的键值。
  4. 平方取中法:这种方法适用于不清楚键值分布的情况,通过计算关键字平方后的中间几位数作为哈希地址。
  5. 折叠法:折叠法将键值分割成几部分,然后将这些部分叠加求和,并取后几位作为散列地址,适用于键值位数较多的情况。
  6. 标准库中的std::hash:C++标准库提供了std::hash模板,它为内置数据类型和一些标准库类型提供了默认的哈希函数实现。对于自定义类型,可以通过特化std::hash模板来提供自定义的哈希函数。

哈希冲突

哈希冲突是指不同的输入值通过哈希函数计算得到了相同的哈希值的现象。

  1. 在哈希表等数据结构中,哈希冲突是不可避免的,因为哈希函数的输出范围通常远小于可能的输入值范围。

解决方法

  • **开放定址法(闭散列):**当发生冲突时,会在哈希表中寻找下一个空位置来存放新元素。常见的开放定址法有线性探测和二次探测。线性探测是从冲突位置开始,依次向后查找空位置;二次探测则是通过更复杂的数学公式来确定下一个探测位置。
  • **再哈希法:**使用一个或多个备用哈希函数来处理冲突,将冲突的元素重新映射到哈希表的其他位置。
  • 链地址法(开散列):在哈希表的每个存储位置不是存储元素本身,而是存储一个指向元素的指针,冲突的元素会被添加到一个链表中。这种方法可以很好地处理大量冲突,但可能会导致链表过长,影响性能。
  • **建立公共溢出区:**为所有可能的哈希冲突预留一个或多个区域,冲突的元素被存储在这些区域中。

**注:**降低哈希冲突是提高效率的一个很好的方法

简单哈希

  • 在数组里面存储结构体
  • 定义哈希要有存在的状态定义了枚举
template<class K,class V>
struct Hashdata
{pair<K, V> _kv;state _state = EMPTY;
};
enum state
{EXIST,EMPTY,DELETE
};

Hash结构

  1. 两个模板参数K V结构
  2. 最后是存储hash的取值,针对整形、浮点型、字符串。进行仿函数的重写
template<class K,class V,class HashFunc = Defaulthashfunc<K>>
class Hash
{
public:private:vector<Hashdata<K, V>> _table;size_t _n = 0;
};

仿函数

  1. 在函数的内容的不确定的时候进行返回。
  2. 针对string字符串的直接进行特模板化。
  3. 针对26字母有不同的组合,要进行字符串的哈希化处理,目的是针对哈希冲突 (本次采用 BKDR算法)参考:字符串哈希算法
template<class K>
struct Defaulthashfunc
{size_t operator()(const K& key){return (size_t)key;}
};template<>
struct Defaulthashfunc<string>
{size_t operator()(const string& str){size_t hash = 0;for (auto e : str){hash *= 131;hash += e;}return hash;}
};

插入

  • 将hash表直接扩容,进行哈希计算
  • 进行哈希扩容 : 不建议直接将哈希表填写满,不利于哈数的查找,将哈希的负载因子(已经存储的数据比总空间的大小)设置到0.7到0.8之间即可。
  • 扩容: 重新定义哈希表(扩容后),进行数据的重新插入,进行交换
  • 进行哈希的冲突的解决
	bool insert(const pair<K, V>& kv){size_t hashi = 0;HashFunc hf;hashi = hf(kv.first) % _table.size();if ((_n * 10 / _table.size()) >= 7){size_t newsize = _table.size() * 2;Hash<K, V, HashFunc> newhash;newhash._table.resize(newsize);for (int i = 0; i < _table.size(); i++){if (_table[i]._state == EXIST){newhash.insert(_table[i]._kv);}}_table.swap(newhash._table);}//线性探测while (_table[hashi]._state == EXIST){++hashi;hashi %= _table.size();}_table[hashi]._kv = kv;_table[hashi]._state = EXIST;++_n;return true;}

开放定址法(闭散列)

发生冲突会在哈希表的另外一个空位置寻找。

//线性探测
while (_table[hashi]._state == EXIST)
{++hashi;hashi %= _table.size();
}_table[hashi]._kv = kv;
_table[hashi]._state = EXIST;
++_n;return true;
}

查找、删除

查找

返回结构体的指针利于后面的额删除

Hashdata<const K, V>* find(const K& key)
{HashFunc hf;size_t hashi = hf(key) % _table.size();while (_table[hashi]._state != EMPTY){if (_table[hashi]._state == EXIST&& _table[hashi]._kv.first == key){return (Hashdata<const K,V>*) & _table[hashi];}++hashi;hashi %= _table.size();}return nullptr;
}

删除

在删除的时候直接进行状态的修改

bool erase(const K& key)
{Hashdata<const K, V>* ret = find(key);if (ret){ret->_state = DELETE;--_n;return true;}return false;}

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

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

相关文章

详解HTTP/HTTPS协议

HTTP HTTP协议全名为超文本传输协议。HTTP协议是应用层协议&#xff0c;其传输层协议采用TCP协议。 请求—响应模型 HTTP协议采用请求-响应模型&#xff0c;通常由客户端发起请求由服务端完成响应。资源存储在服务端&#xff0c;客户端通过请求服务端获取资源。 认识URL 当…

01,大数据总结,zookeeper

1 &#xff0c;zookeeper &#xff1a;概述 1.1&#xff0c;zookeeper&#xff1a;作用 1 &#xff0c;大数据领域 &#xff1a;存储配置数据   例如&#xff1a;hadoop 的 ha 配置信息&#xff0c;hbase 的配置信息&#xff0c;都存储在 zookeeper 2 &#xff0c;应用领…

TDengine 与飞腾腾锐 D2000 完成兼容互认证,推动国产软硬件深度融合

在国家信息安全和自主可控技术日益受到重视的背景下&#xff0c;国产软硬件的发展已成为推动数字经济的重要力量。随着全球科技竞争加剧&#xff0c;企业在选择技术解决方案时&#xff0c;越来越倾向于采用国产产品以降低对外部技术的依赖。这一趋势不仅是为了确保数据安全与隐…

信息安全数学基础(14)欧拉函数

前言 在信息安全数学基础中&#xff0c;欧拉函数&#xff08;Eulers Totient Function&#xff09;是一个非常重要的概念&#xff0c;它与模运算、剩余类、简化剩余系以及密码学中的许多应用紧密相关。欧拉函数用符号 φ(n) 表示&#xff0c;其中 n 是一个正整数。 一、定义 欧…

模拟视频推到WVP推流列表

效果 1. wvp创建RTMP 2. 使用ffmpeg将本地的视频转为rtmp ffmpeg -re -i F:rtsp\123.mp4 -c copy -f flv rtmp://192.168.1.237:1935/cd/10001?sign=Z4Y3eYeSg

标准库标头 <bit>(C++20)学习

<bit>头文件是数值库的一部分。定义用于访问、操作和处理各个位和位序列的函数。例如&#xff0c;有函数可以旋转位、查找连续集或已清除位的数量、查看某个数是否为 2 的整数幂、查找表示数字的最小位数等。 类型 endian (C20) 指示标量类型的端序 (枚举) 函数 bit_ca…

Android权限适配

Android权限适配 动态权限 背景 从Android6.0版本开始google将权限分为普通权限和特殊权限&#xff0c;app必须在AndroidManifest.xml添加引用权限的语句。 在安装apk时安卓会将普通权限授予该app&#xff0c;但特殊权限需要运行时申请。 安卓按照权限类别分为权限组和权限…

【第36章】Spring Cloud之Seata分布式事务

文章目录 前言一、架构图1. 介绍2. 项目结构3. 功能描述 二、用例1. 准备1.1 系统表1.2 业务表1.3 初始化数据 2. 项目搭建2.1 项目结构2.2 主要依赖2.3 主要配置 三、主要业务代码1. 仓储服务1.1 controller1.2 service1.3 dao 2. 订单服务1.1 controller1.2 service1.3 dao 3…

Mac清理其他文件:释放存储空间的高效指南

每个Mac用户都可能遇到存储空间不足的问题&#xff0c;尤其是当“其他”文件积累到一定体积时。在Mac上&#xff0c;“其他”文件通常包括各种系统文件、缓存、文档以及不被归类为应用程序、照片、电影或音乐的其他类型的文件。这些文件往往不易被注意&#xff0c;但逐渐占用了…

【笔记】CCF直播:《如何在国际会议上有效交流》(2024-9-15)

目录 一、提问的勇气二、提问什么三、其他主题的报告为什么听四、会议前怎么读大量论文&#xff1f;五、workshop为什么参加&#xff1f;Poster环节&#xff1f;六、提问环节七、其他 今天听了《如何在国际会议上有效交流》的直播讲座&#xff0c;记录一些笔记。 一、提问的勇…

我又做了一个国标GB28181设备模拟器的Windows版本,让国标28181开发更简单,不用再费劲弄个摄像机来调试国标GB28181开发了

之前我搞过一个《EasyGBD国标GB28181设备端模拟器帮助测试国标GB28181平台&#xff08;EasyGBD-&#xff1e;EasyGBS&#xff09;》&#xff0c;当时&#xff0c;主要是在安卓手机上&#xff0c;用摄像机的本地摄像头来做为视频源、用摄像机的麦克风做为音频源&#xff0c;对外…

微服务网关终极进化:设计模式驱动的性能与可用性优化(四)

时间&#xff1a;2024年09月12日 作者&#xff1a;小蒋聊技术 邮箱&#xff1a;wei_wei10163.com 微信&#xff1a;wei_wei10 希望大家帮个忙&#xff01;如果大家有工作机会&#xff0c;希望帮小蒋推荐一下&#xff0c;小蒋希望遇到一个认真做事的团队&#xff0c;一起努力…

CefSharp_Vue交互(Element UI)_WinFormWeb应用(3)---通过页面锁屏和关机(含示例代码)

一、预览 实现功能:通过vue标题栏按钮锁屏和关机 1.1 预览 1.2 代码 锁屏代码csharp LockWorkStation() 关机代码chsharp 注意vue代码参数和此参数一致(0/1/2) 方法ExitWindowsEx()

python 读取excel

一、安装依赖&#xff1a; pandas 二、新建excel 示例数据&#xff1a;students.xlsx 三、定义类&#xff1a;student.py Student class Student:def __init__(self, name, sex):self.name nameself.sex sexdef show(self):print(f姓名&#xff1a;{self.name} 性别&#…

828华为云征文 | 使用Flexus云服务器X实例部署GLPI资产管理系统

828华为云征文 | 使用Flexus云服务器X实例部署GLPI资产管理系统 1. 部署环境说明2. 部署基础环境2.1. 操作系统基本配置2.2. 部署Nginx2.3. 部署MySQL2.4. 部署PHP 3. 部署GLPI资产管理系统 1. 部署环境说明 本次环境选择使用华为云Flexus云服务器X实例&#xff0c;因为其具有高…

初学Linux(学习笔记)

初学Linux&#xff08;学习笔记&#xff09; 前言 本文跳过了Linux前期的环境准备&#xff0c;直接从知识点和指令开始。 知识点&#xff1a; 1.目录文件夹&#xff08;Windows&#xff09; 2.文件内容属性 3.在Windows当中区分文件类型是通过后缀&#xff0c;而Linux是通过…

【Linux下的cpp】编译调试(gcc、g++、gdb)

【Linux下的cpp】编译调试&#xff08;gcc、g、gdb&#xff09; 文章目录 【Linux下的cpp】编译调试&#xff08;gcc、g、gdb&#xff09;简述gcc、g、gdb编译过程g 编译参数命令行编译演练1、直接编译2、生成库文件并编译链接静态库并生成可执行文件链接动态库生成可执行文件 …

Mistral AI再创新高,Pixtral 12B多模态模型强势来袭

前沿科技速递&#x1f680; 近日&#xff0c;Mistral AI 发布了其首款多模态大模型——Pixtral 12B。作为一款具有语言与视觉处理能力的模型&#xff0c;Pixtral 12B 支持高达10241024像素的图像&#xff0c;具备强大的文本生成、图像理解与生成能力&#xff0c;能够处理复杂的…

Dubbo从入门到实战

Dubbo从入门到实战 1、为什么需要dubbo 很多时候&#xff0c;其实我们使用这个技术的时候&#xff0c;可能都是因为项目需要&#xff0c;所以&#xff0c;我们就用了&#xff0c;但是&#xff0c;至于为什么我们需 要用到这个技术&#xff0c;可能自身并不是很了解的&#x…

【C++STL简介】——我与C++的不解之缘(八)

前言 学过了C的模版&#xff0c;接下来学习C中的STL&#xff08;标准模版库&#xff09;&#xff0c;先来了解一下STL是啥 一、什么是STL STL&#xff08;standard template libaray 标准模版库&#xff09;&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的…