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方法进行初始化设置,…...
ssm+java2026年毕设私教预约系统【源码+论文】
本系统(程序源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、选题背景关于会议管理问题的研究,现有研究主要以传统纸质登记和简单的OA系统为主,专门针对智能化、全流程会议预…...
5分钟搞定三网话费余额查询:手把手教你用PHP+HTML搭建查询系统(含API调用避坑指南)
三网话费查询系统开发实战:从API调用到前端优化的全流程指南 最近在帮朋友开发一个小型话费查询工具时,发现市面上关于三网运营商API调用的完整教程并不多见。大多数开发者遇到问题时只能靠反复试错,特别是当需要同时对接移动、联通、电信三家…...
从‘它怎么又挂了’到‘服务稳如狗’:我是如何用Prometheus+Grafana给自家小项目做监控的
从零搭建轻量级服务监控:PrometheusGrafana实战指南 凌晨三点,手机突然响起刺耳的警报声——这已经是本周第三次被线上服务宕机惊醒。作为独立开发者或小团队,我们往往身兼数职,既要写代码又要维护基础设施。服务崩溃时才发现问题…...
遇到“用户对AIAgent进行提示词注入”怎么办?
文章目录先理解什么是“提示词注入”图片里的防护方法(两层)第一层:System Prompt 先贴“封条”第二层:输出端再加“安检门”总结先理解什么是“提示词注入” 你可以把 Agent(智能助手) 想象成一个 严格遵…...
探索Unity全功能的开源方案:UniHacker跨平台功能扩展工具深度指南
探索Unity全功能的开源方案:UniHacker跨平台功能扩展工具深度指南 【免费下载链接】UniHacker 为Windows、MacOS、Linux和Docker修补所有版本的Unity3D和UnityHub 项目地址: https://gitcode.com/GitHub_Trending/un/UniHacker Unity作为游戏开发领域的行业标…...
造相-Z-Image-Turbo亚洲美女LoRA创作实战:三个案例教你玩转AI绘画
造相-Z-Image-Turbo亚洲美女LoRA创作实战:三个案例教你玩转AI绘画 1. 认识造相-Z-Image-Turbo与亚洲美女LoRA 造相-Z-Image-Turbo是一款强大的AI图片生成模型,而亚洲美女LoRA则是专门针对亚洲人物特征优化的风格适配器。这个组合让普通用户也能轻松创作…...
文明降级运动:回归纸笔抵抗AI监控
在AI技术席卷软件测试领域的浪潮中,一个看似“倒退”却极具战略意义的趋势正在兴起——文明降级运动。这场运动的核心是主动回归纸笔工具,以抵抗AI监控带来的系统性风险。作为软件测试从业者,我们身处技术前沿,见证了AI在缺陷预测…...
大模型RAG入门基础架构介绍
传统大模型的局限性 知识可能过时(训练数据有时效 性)会产生"幻觉"(编造不存在的信息)无法访问私有知识库数据回答缺乏具体出处,难以验证最大对话上下文限制(大部分模型128K) RAG的…...
Beyond Compare 5 三步快速激活方案:从评估错误到专业版授权的完整指南
Beyond Compare 5 三步快速激活方案:从评估错误到专业版授权的完整指南 【免费下载链接】BCompare_Keygen Keygen for BCompare 5 项目地址: https://gitcode.com/gh_mirrors/bc/BCompare_Keygen Beyond Compare 5 作为业界领先的文件比对与合并工具…...
老旧Mac设备焕新:使用开源工具OpenCore Legacy Patcher实现系统升级全攻略
老旧Mac设备焕新:使用开源工具OpenCore Legacy Patcher实现系统升级全攻略 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 一、问题诊断:评估老旧M…...
