C++ unordered_map
1. unordered系列关联式容器
2. unordered_map的介绍
3. unordered_map的使用
1. unordered_map的构造
| 函数声明 | 功能介绍 |
| unordered_map() | 构造不同格式的 unordered_map 对象 |
2. unordered_map的容量
| 函数声明 | 功能介绍 |
| bool empty() const | 检测 unordered_map 是否为空 |
| size_t size() const | 获取 unordered_map 的有效元素个数 |
3. unordered_map的迭代器
| 函数声明 | 功能介绍 |
| iterator begin() | 返回 unordered_map 第一个元素的迭代器 |
| iterator end() | 返回 unordered_map 最后一个元素下一个位置的迭代器 |
| const_iterator cbegin() const | 返回 unordered_map 第一个元素的 const 迭代器 |
| const_iterator cend() const | 返回 unordered_map 最后一个元素下一个位置的 const 迭代器 |
4. unordered_map的元素访问
| 函数声明 | 功能介绍 |
| mapped_type& operator[ ] (const key_type& k) | 返回与 key 对应的 value ,没有返回一个默认值 |
5. unordered_map的查询
| 函数声明 | 功能介绍 |
| iterator find(const K& key) | 返回 key 在哈希桶中的位置 |
| size_t count(const K& key) | 返回哈希桶中关键码为 key 的键值对的个数 |
6. unordered_map的修改操作
| 函数声明 | 功能介绍 |
| pair<iterator,bool> insert (const value_type& x ) | 向容器中插入键值对 |
| size_type erase ( const key_type& x ) | 删除容器中的键值对 |
| void clear() | 清空容器中有效元素个数 |
| void swap(unordered_map&) | 交换两个容器中的元 |
7. unordered_map的桶操作
| 函数声明 | 功能介绍 |
| size_t bucket_count()const | 返回哈希桶中桶的总个数 |
| size_t bucket_size(size_t n)const | 返回 n 号桶中有效元素的总个数 |
| size_t bucket(const K& key) | 返回元素 key 所在的桶号 |
4.unordered_map的模拟实现
首先我们要使用哈希表进行封装unordered_map即可,如下是HashTable.cpp的文件,有关哈希表的详细介绍,可以点击了解C++哈希表。
#include <iostream>
#include <vector>
using namespace std;
namespace OpenHash
{template<class T>struct HashNode{T _data;HashNode* _next;HashNode(const T& data):_data(data), _next(nullptr){}};//将key转换为整型方便取模template <class K>struct Hash{size_t operator()(const K& key){return key;}};//模板特化,将string类型转换为整型template<>class Hash<string>{size_t operator()(const string& s){size_t ret = 0;for (auto e : s){ret = ret * 31 + e;}return ret;}};//实现迭代器//因为迭代器的实现需要借助HashTable,所以需要前置定义template <class K, class T, class KeyOfT, class HashFunc = Hash<K>>class HashTable;template <class K, class T, class Ptr, class Ref, class KeyOfT, class HashFunc = Hash<K>>struct HashTableIterator{typedef typename HashNode<T> Node;typedef typename HashTableIterator<K, T, Ptr, Ref, KeyOfT, HashFunc> Self;typedef typename HashTable<K, T, KeyOfT, HashFunc> HashTable;HashTable* _ht;Node* _node;HashTableIterator() = default;HashTableIterator(const Node*& node, const HashTable*& ht):_ht(ht), _node(node){}Self& operator++(){//遍历当前桶if (_node->_next)_node = _node->_next;//找下一个桶else{KeyOfT kot;HashFunc hf;//获取索引值size_t index = hf(kot(_node->_data)) % _ht->_table.size();++index;while (index < _ht->_table.size() && _ht->_table[index] == nullptr)++index;if (index == _ht->_table.size())_node = nullptr;else_node = _ht->_table[index];}return *this;}Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}bool operator==(const Self& s){return _node == s._node;}bool operator!=(const Self& s){return _node != s._node;}};template <class K, class T, class KeyOfT, class HashFunc>class HashTable{public://友元(因为iterator需要用到_table)template <class K, class T, class Ptr, class Ref, class KeyOfT, class HashFunc>friend struct HashTableIterator;typedef typename HashNode<T> Node;typedef typename HashTableIterator<K, T, T*, T&, KeyOfT, HashFunc> iterator;//构造函数HashTable():_table(vector<Node*>()), _n(0){}iterator begin(){for (size_t i = 0; i < _table.size(); i++){if (_table[i])return iterator(_table[i], this);}return iterator(nullptr, this);}iterator end(){return iterator(nullptr, this);}iterator find(const K& key){if (_table.size() == 0){return iterator(nullptr, this);}KeyOfT kot;HashFunc hf;size_t index = hf(key) % _table.size();Node* cur = _table[index];while (cur){if (kot(cur->_data) == key)return iterator(cur, this);cur = cur->_next;}return iterator(nullptr, this);}pair<iterator, bool> insert(const K& key){//第一次插入需要扩容if (_table.size() == 0)_table.resize(10);//不能出现重复数据if (find(key) != iterator(nullptr, this)){return make_pair(find(key), false);}KeyOfT kot;HashFunc hf;//桶的个数是一定的,随着元素的不断插入,每个桶中元素的个数不断增多,极端情况下,//可能会导致一个桶中链表节点非常多,会影响的哈希表的性能,因此在一定条件下需要对//哈希表进行增容,那该条件怎么确认呢?开散列最好的情况是:每个哈希桶中刚好挂一个//节点,再继续插入元素时,每一次都会发生哈希冲突,因此,在元素个数刚好等于桶的个数//时,可以给哈希表增容。//负载因子到1,需要扩容if (_n == _table.size()){vector<Node*> newtable;newtable.resize(_table.size() * 2);//重新映射到新表for (auto e : _table){Node* cur = e;while (cur){size_t index = hf(kot(cur->_data)) % newtable.size();cur->_next = newtable[index];newtable[index] = cur;cur = cur->_next;}}}size_t index = hf(key) % _table.size();Node*& cur = _table[index];while (cur)cur = cur->_next;cur = new Node(key);return make_pair(iterator(cur, this), true);}bool erase(const K& key){KeyOfT kot;HashFunc hf;size_t index = hf(key) % _table.size();Node* cur = _table[index], * pre = _table[index];while (cur){if (kot(cur->_data) == key){//要删除该位置第一个元素if (cur == pre)_table[index] = cur->_next;elsepre->_next = cur->_next;delete cur;_n--;return true;}pre = cur;cur = cur->_next;}return false;}private:vector<Node*> _table;size_t _n;//有效数据个数};
} unordered_map.cpp文件如下
#include"HashTable.cpp"
namespace lbk
{template<class K,class Hash=OpenHash::Hash<K>>class unordered_set{struct SetKeyOfT{const K& operator()(const K& key){return key;}};public:typedef typename OpenHash::HashTable<K,K,SetKeyOfT,Hash>::iterator iterator;iterator begin(){return _ht.begin();}iterator end(){return _ht.end();}iterator find(const K& key){return _ht.find(key);}pair<iterator, bool> insert(const K& key){return _ht.insert(key);}bool erase(const K& key){return _ht.erase(key);}private:OpenHash::HashTable<K, K, SetKeyOfT, Hash> _ht;};
} 相关文章:
C++ unordered_map
1. unordered系列关联式容器 在C98 中, STL 提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 ,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是,…...
PHP Switch 语句
PHP 中的 switch 语句是一种多路分支语句,它允许一个变量的值对多个代码块进行选择执行。这通常比使用多个 if...elseif...else 语句更清晰、更易于维护。下面将详细介绍 PHP 中 switch 语句的使用方法。 基本语法 switch (n) {case label1:// 如果 n label1&…...
electron 网页TodoList应用打包win桌面软件数据持久化
参考: electron 网页TodoList工具打包成win桌面应用exe https://blog.csdn.net/weixin_42357472/article/details/140648621 electron直接打包exe应用,打开网页上面添加的task在重启后为空,历史没有被保存,需要持久化工具保存之前…...
软件缺陷(Bug)、禅道
目录 软件缺陷的判定标准 软件缺陷的核心内容 构成缺陷的基本要素 缺陷报告 缺陷管理 缺陷的跟踪流程 项目管理工具--禅道 软件在使用过程中存在的任何问题(如:错误、异常等),都叫软件的缺陷,简称bug。 软件缺…...
MySQL客户端命令一节将.sql文件导入MySQL
MySql客户端命令 直接输入SQL语句 使用MySQL客户端连接到服务器之后,可以发送SQL语句到服务器执行,并且以;和\g, \G作为结束不同的结束方式显示内容有所不同** TIPS: ;和\g结尾以表格的形式显示结果\G以行的形式显示结果 在连接到服务器之后…...
[论文笔记] DCA(Dual Chunk Attention)
DCA(Dual Chunk Attention)是一种在自然语言处理模型中用来处理长文本的技术。传统的注意力机制(Attention)在处理长文本时可能会遇到效率和性能瓶颈,因为计算每个单词与其他所有单词之间的关系会随着文本长度的增加而…...
构建查询洞察 UI
本文字数:2631;估计阅读时间:7 分钟 作者:Bucky Schwarz 本文在公众号【ClickHouseInc】首发 我们最近发布了 Query Insights 的初步实现,为 ClickHouse Cloud 用户提供了一种便捷的方法来查看和解释查询日志。该功能对…...
【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第五十九章 等待队列
i.MX8MM处理器采用了先进的14LPCFinFET工艺,提供更快的速度和更高的电源效率;四核Cortex-A53,单核Cortex-M4,多达五个内核 ,主频高达1.8GHz,2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…...
35.【C语言】详解函数递归
目录: 定义 作用 例子1~3 拓展学习 趣味练习 1.定义:函数自己调用自己(递推回归) int main() {main()return 0; } 这样容易死循环,导致爆栈(Stack Overflow) 所以需要设立限制条件,使执行时越来越接近条…...
【机器学习】智驭未来:机器学习如何重塑制造业的转型与升级
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀目录 🔍1. 引言📒2. 机器学习重塑制造业生产流程🌸预测性维护:减少停机时间,提高设…...
Python爬虫(5) --爬取网页视频
文章目录 爬虫爬取视频指定url发送请求UA伪装请求页面 获取想要的数据解析定位定位音视频位置 存放视频完整代码实现总结 爬虫 Python 爬虫是一种自动化工具,用于从互联网上抓取网页数据并提取有用的信息。Python 因其简洁的语法和丰富的库支持(如 requ…...
【Unity】关于Luban的简单使用
最近看了下Luban导出Excel数据的方式,来记录下 【Unity】关于Luban的简单使用 安装Luban开始使用UnityLubanC# 扩展 安装Luban Luban文档:https://luban.doc.code-philosophy.com/docs/beginner/quickstart 1.安装dotnet sdk 8.0或更高版本sdk 2.githu…...
企业公户验证API如何使用JAVA、Python、PHP语言进行应用
在纷繁复杂的金融与商业领域,确保每笔交易的安全与合规是至关重要的。而企业公户验证API,正是这样一位默默守护的数字卫士,它通过智能化的手段,简化了企业对公账户验证流程,让繁琐的审核变得快捷且可靠。 什么是企业公…...
杰发科技Bootloader(2)—— 基于7840的Keil配置地址
序 在7840的sample代码里面有一个简单的Boot跳转APP的示例 PFlash地址从0开始 DFlash的地址从1000000开始 Boot解析 他的boot地址配置为0 Boot的代码主要是这几行,主要作用就是Flash的跳转 int main(void) {SystemClock_Config();InitDebug();printf("demo…...
cmd常用命令
在Windows操作系统中,CMD(Command Prompt)是一个强大的命令行工具,允许用户通过键入命令来执行各种系统级操作。以下是一些常用的CMD命令及其功能: 文件与目录管理 dir:显示当前目录下的文件和子目录列表。…...
PCIe 以太网芯片 RTL8125B 的 spec 和 Linux driver 分析备忘
1,下载 RTL8125B driver 下载页: https://www.realtek.com/Download/List?cate_id584 2,RTL8125B datasheet下载 下载页: https://file.elecfans.com/web2/M00/44/D8/poYBAGKHVriAHnfWADAT6T6hjVk715.pdf3, 编译driver 解压: $ tar xj…...
Python tkinter Menu菜单组件详解
好久没有更新了,今天我来领大家熟悉一下Menu组件 1.认识、了解Menu 什么是Menu menu组件是tkinter中的菜单组件,通过该组件,开发者可以为窗口设计菜单和工具栏等。(ttk还提供了treeview树形菜单,python遍历目录的两种…...
谷粒商城实战笔记-46-商品服务-API-三级分类-配置网关路由与路径重写
文章目录 一,准备工作1,新增一级菜单2,新增二级菜单 二,前端树形界面开发1,开发分类展示组件 三,远程调用接口获取商品分类数据1,远程调用2,路由配置 错误记录 本节的主要内容&#…...
简要了解sql注入
sql注入安全测试中危害 数据库中的数据,对数据库数据进行操作(查询、删除等);网站的权限,找到注入点后可后门写入; sql注入产生原理详细分析 可控变量,带入数据库查询,变量未存在…...
Java 扫雷游戏
程序分析 使用Java编写的扫雷游戏界面程序,主要内容总结如下: Frame类继承自JFrame,构建了扫雷游戏的界面。 包含文本框text、标签nowBomb和setBomb、按钮start、面板MenuPamel和bombPanel等组件。通过jbInit方法进行初始化设置,…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
一、前言 在HarmonyOS 5的应用开发模型中,featureAbility是旧版FA模型(Feature Ability)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文获取方式,而非依赖featureAbility。 FA大概是API7之…...
从零开始了解数据采集(二十八)——制造业数字孪生
近年来,我国的工业领域正经历一场前所未有的数字化变革,从“双碳目标”到工业互联网平台的推广,国家政策和市场需求共同推动了制造业的升级。在这场变革中,数字孪生技术成为备受关注的关键工具,它不仅让企业“看见”设…...
Python环境安装与虚拟环境配置详解
本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南,适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者,都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...
