当前位置: 首页 > news >正文

C++哈希介绍

好的,这是一个关于 C++ 中“哈希”的全面介绍。在 C++ 中,哈希主要通过无序关联容器哈希函数对象来实现。


一、核心容器:无序关联容器

C++11 引入了基于哈希表实现的容器,它们提供了平均 O(1) 时间复杂度的查找、插入和删除操作。

容器

头文件

特点

std::unordered_set

<unordered_set>

唯一键的集合,快速判断元素是否存在。

std::unordered_multiset

<unordered_set>

键可重复的集合。

std::unordered_map

<unordered_map>

键值对,键唯一。

std::unordered_multimap

<unordered_map>

键值对,键可重复。

与有序容器对比:

  • 有序容器​ (std::map,std::set):基于红黑树,元素按键排序,操作 O(log n)。

  • 无序容器:基于哈希表,元素无序,平均 O(1),最差 O(n)(哈希冲突极端情况)。

示例:std::unordered_map基本用法

#include <iostream> #include <unordered_map> #include <string> int main() { std::unordered_map<std::string, int> ageMap; // 插入 ageMap["Alice"] = 30; ageMap["Bob"] = 25; ageMap.insert({"Charlie", 28}); // 查找 (使用 find 避免自动创建) auto it = ageMap.find("Bob"); if (it != ageMap.end()) { std::cout << "Bob's age: " << it->second << std::endl; // 输出 25 } // 遍历(顺序不确定!) for (const auto& pair : ageMap) { std::cout << pair.first << ": " << pair.second << std::endl; } return 0; }

二、关键组件:哈希函数与相等比较

无序容器的实现依赖于两个核心函数对象:

  1. 哈希函数:将键映射到一个size_t类型的哈希值。

    • 标准库为内置类型和std::string等提供了特化版本。

    • 必须满足:如果两个键相等,它们的哈希值必须相等

  2. 相等比较函数:用于处理哈希冲突(当两个不同键产生相同哈希值时,判断它们是否真的相等)。

自定义哈希函数示例:为一个自定义的Person类创建哈希。

#include <unordered_set> struct Person { std::string name; int id; // 1. 必须定义相等运算符 (==) bool operator==(const Person& other) const { return name == other.name && id == other.id; } }; // 2. 自定义哈希函数 struct PersonHash { std::size_t operator()(const Person& p) const { // 组合成员变量的哈希值 return std::hash<std::string>{}(p.name) ^ (std::hash<int>{}(p.id) << 1); } }; int main() { // 使用自定义哈希和相等比较 std::unordered_set<Person, PersonHash> peopleSet; peopleSet.insert({"Alice", 1}); peopleSet.insert({"Bob", 2}); return 0; }

三、进阶:性能与策略

  1. 负载因子容器内元素数量 / 桶数量

    • 通过load_factor()获取,max_load_factor()获取/设置最大负载因子(默认 1.0)。

    • 当负载因子超过阈值,容器会自动扩容(增加桶数并重新哈希所有元素)。

  2. 桶接口:可直接操作底层桶。

    std::unordered_map<int, int> map; // 获取桶数量 size_t bucketCount = map.bucket_count(); // 获取特定键所在的桶索引 size_t bucketIndex = map.bucket(key);
  3. 自定义内存分配:可指定自定义的分配器。


四、C++ 标准中的哈希支持

  • std::hash特化:标准库在<functional>中为内置类型、std::stringstd::unique_ptr等提供了std::hash的特化版本。

  • std::hash组合:在 C++11 后,可方便组合多个哈希值。

    struct PairHash { template <class T1, class T2> std::size_t operator()(const std::pair<T1, T2>& p) const { auto h1 = std::hash<T1>{}(p.first); auto h2 = std::hash<T2>{}(p.second); return h1 ^ (h2 << 1); } };

五、最佳实践与注意事项

  1. 选择容器

    • 需要有序遍历​ → 用std::map/std::set

    • 需要快速查找且不关心顺序 → 用std::unordered_map/std::unordered_set

  2. 自定义类型作为键

    • 必须提供自定义哈希函数(如PersonHash

    • 必须重载operator==

  3. 性能调优

    • 如果键空间已知,可提前用reserve()预留空间,避免多次重哈希。

    • 哈希函数应尽量均匀分布,避免聚集。

  4. 线程安全

    • 无序容器本身不是线程安全的,多线程读写需要外部同步。


总结表格

特性

说明

底层实现

哈希表(数组 + 链表/红黑树)

时间复杂度

平均 O(1),最差 O(n)

元素顺序

无序(但按桶顺序遍历)

自定义键

需提供哈希函数和operator==

内存开销

高于有序容器(维护桶数组)

典型应用

缓存、快速查找表、去重

C++ 的哈希机制提供了高性能的查找能力,是编写高效程序的重要工具。理解其原理和调优方法,能帮助你在实际项目中做出最佳选择。

http://www.gsyq.cn/news/1335082.html

相关文章:

  • k8s集群网络层碎碎念
  • COLMAP重建翻车实录:当你的相机内外参已知,却卡在database.db和images.txt对不上?
  • 城市网格化治理平台
  • 用TensorRT加速你的YOLOv5:Windows C++推理部署实战(附完整项目配置)
  • 视频融合平台:服务正常运行但没有画面
  • 采购新手怎么快速上手?3个步骤搞定采购流程
  • TPU里的“心脏”怎么工作?用Python动画+Verilog仿真,可视化脉动阵列数据流
  • 5.1二维数组与矩阵乘法
  • 18V/4A同步降压转换器:MPQ8632GLE-4的COT控制与快速瞬态响应解析
  • 【Perplexity阅读推荐查询实战指南】:20年AI工具专家亲授5大精准筛选技巧,错过再等一年
  • 2460亿个数据点告诉你,人是一瞬间变老的
  • 保姆级教程:用Python+OpenCV实现无人机吊舱图像与卫星地图的自动匹配(附代码)
  • 打造 Linux 离线大模型级语音输入法:Whisper.cpp + 3090 显卡加速与 Rime 中英混输终极调优指南
  • Keil5调试效率翻倍指南:除了单步运行,这些高级窗口你用过吗?(含System Viewer/Command Window实战)
  • C++调试小技巧:除了typeid,还有哪些方法能动态查看变量类型?(附代码示例)
  • 苏州小微企业财税外包服务机构推荐排行盘点:苏州注册公司地址挂靠、苏州注册园区地址挂靠、苏州网上申请注册、苏州财务公司代理记账选择指南 - 优质品牌商家
  • 创业团队如何借助taotoken低成本快速验证多个ai产品创意原型
  • 2026苏州注册资金认缴服务机构排行实测盘点:苏州公司注册开户、苏州公司营业执照办理、苏州兼职会计代账、苏州小微企业财税外包选择指南 - 优质品牌商家
  • LabelImg标注VOC数据集避坑指南:从安装到批量标注的完整工作流
  • 5个真正赚钱的 AI 工作流 (2026)
  • 半波整流电路:从原理到实践,掌握AC-DC转换基础
  • 2026白蚁防治技术分享:潮州白蚁消杀、玉林白蚁消杀、绵阳白蚁消杀、莆田白蚁消杀、衡阳白蚁消杀、赣州白蚁消杀、邵阳白蚁消杀选择指南 - 优质品牌商家
  • 刚发布的Perplexity v2.4.1词汇增强模块,已悄悄接入BERT-wwm-ext蒸馏模型——内测权限仅剩最后47个名额
  • Linux符号链接原理与实战:从快捷方式到系统管理核心技能
  • Java Snowy框架CI/CD云效自动化部署流程
  • 超实用!PS 修改截图文字最简单方法,自然无破绽
  • 复旦微FM33FR0xx开发板实战:从零构建低功耗电容触摸应用
  • 电磁炉电源保护:压敏电阻工作原理、选型与故障排查全解析
  • 从开发者视角分享Taotoken文档与示例代码的上手便捷度
  • 基于协同过滤算法的绿色食品推荐系统(10075)