C++ 容器——unordered_xxx

       自 C++11 开始,STL 引入了基于 hash table 的 unordered_setunordered_map 等容器,正如其名它们是无序容器。一定数量(据说有测试数据是10000000)元素时无序容器的性能要比对应的有序容器优。

一、容器数据结构

        unordered_set、unordered_map 等容器的 Hash Table(哈希表/散列表)结构通常是:桶(bucket) + 线性表,bucket 一般用 vector 实现,线性表通常采用链表。当插入元素时通过哈希函数计算其哈希值,以哈希值作为 vector 的下标索引,取得元素要插入的链表头,把元素插入进去。也就是说通过 链地址法(Separate Chaining)  解决哈希冲突。

二、哈希函数

        哈希函数是这些容器的核心,也是保证它们高性能的关键。C++11 为基本类型:int、float、double、char、string 提供了哈希函数。 但是要在这些容器中添加自定义类型的元素就必须提供特定的哈希函数

无自定义类的哈希函数

无论是 clang++、还是 g++ 都无法正确如下代码,原因就是:缺失计算 Person 哈希值的函数

#include <string>
#include <unordered_set>class Person {
public:Person(const std::string &name, int age) : _name(name), _age(age) {}private:std::string _name;int         _age;
};int main(int argc, char *argv[]) {std::unordered_set<Person> persons;
}
为自定义类添加哈希函数

查看 unordered_set 的声明、 g++ 的 /usr/include/c++/9/bits/functional_hash.h 可知:

  • unordered_set 的模板参数 Hash 默认设置为 std::hash<Key>,std::hash 是一个类模板;
  • 通过特化 std::hash,支持了诸如 int、double 基本类型的哈希函数;
  • 每个特化版本中重载了函数调用运算符
template<class Key,class Hash = std::hash<Key>,class KeyEqual = std::equal_to<Key>,class Allocator = std::allocator<Key>
> class unordered_set;/// Explicit specialization for int.
_Cxx_hashtable_define_trivial_hash(int)/// Explicit specialization for bool.
_Cxx_hashtable_define_trivial_hash(bool)/// Explicit specialization for char.
_Cxx_hashtable_define_trivial_hash(char)#define _Cxx_hashtable_define_trivial_hash(_Tp) 	\template<>						\struct hash<_Tp> : public __hash_base<size_t, _Tp>  \{                                                   \size_t                                            \operator()(_Tp __val) const noexcept              \{ return static_cast<size_t>(__val); }            \};

综述为 Person 类定义函数对象类实现哈希函数功能

#include <string>
#include <unordered_set>struct Person {Person(const std::string &name, int age) : _name(name), _age(age) {}std::string _name;int         _age;
};struct PersonHash
{size_t operator()(const Person &person) const noexcept{return static_cast<size_t>(person._age + person._name.length());}
};int main(int argc, char *argv[]) {std::unordered_set<Person, PersonHash> persons;persons.insert({"yaoyuan", 30});}
为自定义类添加哈希函数

未完...

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

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

相关文章

分布式常见面试题整理

一、分布式理论&#xff1a; CAP理论 分布式系统最多同时满足一致性&#xff08;C&#xff09;、可用性&#xff08;A&#xff09;、分区容错性&#xff08;P&#xff09;中的两个&#xff0c;无法三者兼得。 BASE理论 对CAP中一致性和可用性的权衡&#xff0c;强调基本可用&a…

Python基础入门常用198英语单词详解

最近&#xff0c;我总结了一份Python学习者入门常用单词表&#xff0c;列出了Python学习中常见的198个高频单词&#xff0c;供初学者学习使用。 这些单词都比较简单&#xff0c;非常易于理解&#xff0c;在掌握好单词的基础上&#xff0c;再去学Python可以达到事半功倍的效果。…

EP-SPY 網路追蹤規避實驗:山脈通聯測試

EP-SPY V3.0 https://github.com/MartinxMax/ep-spy 基於 GI6E 編碼的無線電通信工具&#xff0c;用於保護您的隱私。 https://github.com/MartinxMax/gi6e 編寫了偽協議以防止內容被解密無法通過網絡追蹤&#xff0c;抵抗官方監控無線音頻廣播&#xff0c;用於隱蔽信息傳輸…

苹果 FoundationModels 秘典侠客行:隐私为先的端侧 AI 江湖

引子 话说侠客岛之上&#xff0c;有一对年轻侠侣 ——「青锋剑客」凌云与「素心仙子」苏凝&#xff0c;二人自幼习武&#xff0c;尤擅拆解各路奇功秘籍。 近日听闻苹果谷&#xff08;Apple&#xff09;于 WWDC 2025 武林大会之上&#xff0c;亮出一门全新绝学「FoundationMod…

华为基于IPD的产品质量计划模板

目录 模板:产品质量计划模板....................................... 1 1. 介绍...................................................................... 5 1.1. 范围和目的.................................................... 5 1.2. 参考资料..…

事务管理的选择:为何 @Transactional 并非万能,TransactionTemplate 更值得信赖

在 Spring 生态的后端开发中&#xff0c;事务管理是保障数据一致性的核心环节。开发者常常会使用 Transactional 注解快速开启事务&#xff0c;一行代码似乎就能解决问题。但随着业务复杂度提升&#xff0c;这种“简单”的背后往往隐藏着难以察觉的隐患。本文将深入剖析 Spring…

CodePerfAI体验:AI代码性能分析工具如何高效排查性能瓶颈、优化SQL执行耗时?

前阵子帮同事排查用户下单接口的性能问题时&#xff0c;我算是真切感受到 “找性能瓶颈比写代码还磨人”—— 接口偶尔会突然卡到 3 秒以上&#xff0c;查日志只看到 “SQL 执行耗时过长”&#xff0c;但具体是哪个查询慢、为什么慢&#xff0c;翻了半天监控也没头绪&#xff0…

《sklearn机器学习——绘制分数以评估模型》验证曲线、学习曲线

估计器的偏差、方差和噪声 每一个估计器都有其优势和劣势。它的泛化误差可以分解为偏差、方差和噪声。估计器的偏差是不同训练集的平均误差。估计器的方差表示对不同训练集&#xff0c;模型的敏感度。噪声是数据的特质。 在下图中&#xff0c;可以看见一个函数 f(x)cos⁡32πxf…

2025年AI PPT必修课-汇报中AI相关内容的“陷阱”与“亮点”

《2025年AI PPT必修课-汇报中AI相关内容的“陷阱”与“亮点”》 (适用于方案汇报、战略PPT、标书/投资人演示)一、内容类坑&#xff08;战略/趋势层面&#xff09;❌ Pitfall (不要写)✅ Correct Expression (推荐写法)Why (原因)还在强调 Caffe / Theano / TF1.x / LSTM采用 P…

Java数据结构 - 顺序表模拟实现与使用

目录1.顺序表的基本介绍2.顺序表的模拟实现2.1 常见的功能2.2 基本框架2.3 方法的实现2.3.1 add方法2.3.2 size方法2.3.3 display方法2.3.4 add&#xff08;int pos&#xff0c;E data)方法2.3.5 remove方法2.3.6 get方法2.3.7 contain方法2.3.8 indexOf方法2.3.9 set方法2.3.1…

rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(二十六)windows平台运行时隐藏控制台

1、主程序第一句添加&#xff1a; 必须放在所有代码第一句 #![cfg_attr(windows, windows_subsystem "windows")]2、 编译命令&#xff1a;cargo build --release3、 编译完成后运行可执行文件&#xff1a; 项目目录/target/release/项目名.exe

什么是静态住宅IP 跨境电商为什么要用静态住宅IP

静态住宅IP的定义静态住宅IP是指由互联网服务提供商&#xff08;ISP&#xff09;分配给家庭用户的固定IP地址。与动态IP不同&#xff0c;静态IP不会频繁变动&#xff0c;长期保持稳定。其特点包括&#xff1a;固定性&#xff1a;IP地址长期不变&#xff0c;适合需要稳定网络环境…

RabbitMQ 初步认识

目录 1. 基本概念 2. RabbitMq 的工作流程 3. 协议 4. 简单的生产者, 消费者模型 4.1 我们先引入 rabbitmq 的依赖 4.2 生产者 4.3 消费者 1. 基本概念 Pruducer : 生产者, 产生消息Consumer : 消费者, 消费消息Broker : RabbitMq Server, 用来接收和发送消息Connectio…

Redis(46) 如何搭建Redis哨兵?

搭建 Redis 哨兵&#xff08;Sentinel&#xff09;集群&#xff0c;确保 Redis 服务具有高可用性。以下是详细的步骤&#xff0c;从 Redis 安装、配置主从复制到配置和启动 Sentinel 集群&#xff0c;并结合相关的代码示例。 步骤 1&#xff1a;安装 Redis 首先&#xff0c;需要…

Grafana 多指标相乘

PromQL中多指标相乘 PromQL表达式&#xff1a; 0.045 * h9_daily_income{coin"nock"} * h9_pool_price_cny{coin"nock"}&#x1f4c8; 基础&#xff1a;单指标运算 常数与指标相乘 在PromQL中&#xff0c;常数与指标的乘法是最简单的运算&#xff1a; # ✅…

【微服务】springboot3 集成 Flink CDC 1.17 实现mysql数据同步

目录 一、前言 二、常用的数据同步解决方案 2.1 为什么需要数据同步 2.2 常用的数据同步方案 2.2.1 Debezium 2.2.2 DataX 2.2.3 Canal 2.2.4 Sqoop 2.2.5 Kettle 2.2.6 Flink CDC 三、Flink CDC介绍 3.1 Flink CDC 概述 3.1.1 Flink CDC 工作原理 3.2 Flink CDC…

分布式数据架构

分布式数据架构是一种将数据分散存储在多台独立计算机&#xff08;节点&#xff09;上&#xff0c;并通过网络协调工作的系统设计。其核心目标是解决海量数据处理、高并发访问、高可用性及可扩展性等传统集中式数据库难以应对的挑战。以下是关键要点解析&#xff1a;一、核心原…

Spark 中spark.implicits._ 中的 toDF和DataFrame 类本身的 toDF 方法

1. spark.implicits._ 中的 toDF&#xff08;隐式转换方法&#xff09;本质这是一个隐式转换&#xff08;implicit conversion&#xff09;&#xff0c;通过 import spark.implicits._ 被引入到作用域中。它的作用是为本地 Scala 集合&#xff08;如 Seq, List, Array 等&#…

如何在MacOS上卸载并且重新安装Homebrew

Homebrew是一款针对macOS操作系统的包管理工具&#xff0c;它允许用户通过命令行界面轻松安装、升级和管理各种开源软件包和工具。Homebrew是一个非常流行的工具&#xff0c;用于简化macOS系统上的软件安装和管理过程。一、卸载 Homebrew方法1&#xff1a;官方卸载脚本&#xf…

如何简单理解状态机、流程图和时序图

状态机、流程图和时序图都是软件工程中用来描述系统行为的工具&#xff0c;但它们像不同的“眼镜”一样&#xff0c;帮助我们从不同角度看问题。下面用生活比喻来简单理解思路&#xff1a;状态机&#xff1a;想象一个交通信号灯。它总是在“红灯”“黄灯”“绿灯”这些状态之间…