新闻中心

c++怎么自定义哈希函数用于unordered_map_c++ unordered_map自定义哈希函数教程

2025-11-15
浏览次数:
返回列表
在C++中使用自定义类型作为unordered_map的键时,需提供哈希函数和相等比较。1. 可通过定义仿函数或lambda实现哈希函数;2. 结构体需重载operator==;3. 哈希设计应减少冲突,推荐组合标准哈希并引入扰动。

c++怎么自定义哈希函数用于unordered_map_c++ unordered_map自定义哈希函数教程

在 C++ 中使用 unordered_map 时,如果键的类型不是内置类型(如 int、string),就需要自定义哈希函数。这是因为 unordered_map 内部依赖哈希表实现,需要一个能将键转换为哈希值的函数。

1. 自定义哈希函数的基本方式

可以通过两种常见方式为 unordered_map 提供自定义哈希函数:

  • 定义一个函数对象(仿函数)
  • 使用 lambda(需配合构造函数传参)

下面以自定义结构体为例说明。

2. 示例:用结构体作为 key

假设我们有一个表示二维点的结构体 Point,想把它作为 unordered_map 的键:

#include <iostream>
#include <unordered_map>

struct Point {
    int x, y;
    Point(int x, int y) : x(x), y(y) {}
    
    // 为了让 unordered_map 正常工作,还需要定义 operator==
    bool operator==(const Point& other) const {
        return x == other.x && y == other.y;
    }
};

// 自定义哈希函数对象
struct HashFunction {
    size_t operator()(const Point& p) const {
        // 简单哈希:将 x 和 y 混合
        return std::hash<int>{}(p.x) ^ (std::hash<int>{}(p.y) << 1);
    }
};

然后就可以这样使用:

Reachout.ai Reachout.ai

一个AI驱动的视频开发平台,专为忙碌的企业家和销售团队打造

Reachout.ai 142 查看详情 Reachout.ai
std::unordered_map<Point, std::string, HashFunction> pointMap;
pointMap[Point(1, 2)] = "origin";
pointMap[Point(3, 4)] = "target";

for (const auto& [key, value] : pointMap) {
    std::cout << "(" << key.x << ", " << key.y << "): " << value << "\n";
}

3. 使用 Lambda 表达式(局部定义)

如果你只想在某个作用域内使用自定义哈希,可以用 lambda,但注意不能直接作为模板参数(lambda 类型无法命名),需要借助其他手段,比如:

auto hash = [](const Point& p) {
    return std::hash<int>{}(p.x) ^ (std::hash<int>{}(p.y) << 1);
};

// 需要同时提供相等比较
auto equal = [](const Point& a, const Point& b) {
    return a.x == b.x && a.y == b.y;
};

std::unordered_map<Point, std::string, decltype(hash), decltype(equal)> map(8, hash, equal);

注意这里必须指定初始桶数(如 8)、哈希函数和等于函数,否则会报错。

4. 哈希函数设计建议

  • 尽量让不同输入产生不同的哈希值,减少冲突
  • 可以组合标准类型的哈希,例如使用 std::hash<t></t>
  • 避免简单异或,尤其是对称字段(如 x 和 y 互换后哈希相同),可加入位移或乘法扰动
  • 推荐写法(更健壮):
size_t operator()(const Point& p) const {
    size_t h1 = std::hash<int>{}(p.x);
    size_t h2 = std::hash<int>{}(p.y);
    return h1 ^ (h2 << 1 | h2 >> (sizeof(size_t)*8-1)); // 引入旋转扰动
}

或者使用官方推荐的哈希组合方法(C++ 标准未提供,但可手动实现):

template<class T>
void hash_combine(size_t& seed, const T& v) {
    seed ^= std::hash<T>{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}

size_t operator()(const Point& p) const {
    size_t seed = 0;
    hash_combine(seed, p.x);
    hash_combine(seed, p.y);
    return seed;
}

这种方式能有效降低哈希碰撞概率。

基本上就这些。只要提供哈希函数和相等比较,并重载 operator== 或指定 equals 函数,就能让任意类型作为 unordered_map 的键。

以上就是c++++怎么自定义哈希函数用于unordered_map_c++ unordered_map自定义哈希函数教程的详细内容,更多请关注其它相关文章!


# 相关文章  # seo大佬讲解  # 江苏创意营销推广  # 网站建设优去文涛  # 北仑区古典家装网站建设  # 网站建设找谁做  # 如何做好网站权重优化  # seo培训学历  # 朝阳区网站建设什么价格  # 江津放心的seo公司  # 盐田网站推广制作  # 中文网  # 可以通过  # c++  # 可以用  # 两种  # 尤其是  # 如果你  # 正确处理  # 如何处理  # 自定义  # red  # 作用域  # stream  # ios 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 火狐浏览器占用内存高卡顿怎么办 火狐浏览器性能优化设置技巧  顺丰快递查询系统 官方正版查询入口  yy漫画网页版官方入口_yy漫画官网登录页面链接  如何在Python中使用Optional类型处理可变对象并避免Pylint警告  sublime如何优雅地处理行尾空格_sublime自动清理多余空白字符配置  我的世界官方游戏入口 我的世界官网平台直达链接  CSS Flexbox与媒体查询:实现响应式布局中元素的并排与堆叠  wps文字怎么插入目录并自动更新_wps文字如何插入目录并自动更新方法  TikTok国际版网页端快速入口 TikTok全球版短视频浏览教程  CSS子选择器:如何区分并样式化嵌套列表的子层级  Composer的 "conflict" 字段有什么用_如何声明不兼容的包以避免依赖冲突  WordPress插件开发:正确注册卸载钩子与避免常见陷阱  J*aScript中向JSON对象添加新属性的正确姿势  如何为你的Composer包编写自动化测试_集成PHPUnit到Composer的scripts工作流  可靠CSGO开箱平台解析 CSGO开箱网合集  Win11怎么开启高性能模式_Windows 11电源计划优化设置  sublime侧边栏怎么增强功能_SideBarEnhancements for sublime安装与配置  Python中如何避免重复条件判断:利用数据结构实现动态逻辑  Golang如何通过reflect操作map_Golang reflect map操作与遍历技巧  HTML空白字符处理机制:渲染、DOM与编码实践  蛙漫正版漫画平台入口_蛙漫免费阅读全站漫画资源  创客贴用户入口官网登录 创客贴网页版电脑版系统  poki免费入口快捷访问 poki人气小游戏直接玩站点  ACG动漫手机版官网入口 手机ACG动漫APP在线观看正版  win11专注助手在哪 Win11免打扰模式设置与自动化规则【指南】  利用Bokeh CustomJS动态控制DataTable列可见性  内存疯狂猛猛涨价:主板销量直接腰斩!  解决Python logging 中 datefmt 导致时间戳固定不变的问题  poki网页游戏推荐_poki免费游戏平台入口  在Typer应用中优雅地处理和重组任意命令行参数  CSS如何设置hover状态颜色_hover伪类调整背景或文字颜色  在React函数组件中利用原生HTML5进行邮箱地址验证  Spring Boot嵌入式服务器与J*a EE:功能支持深度解析  印象笔记如何设离线包出差查阅_印象笔记设离线包出差查阅【离线阅读】  J*aScript实现动态背景色下的文本与按钮颜色自适应调整  C++如何实现单例模式_C++设计模式之线程安全的单例写法  大象笔记网页版入口 印象笔记网页版登录入口  处理嵌套交互式控件:前端可访问性指南  深入理解rpy2中的类型转换:优化Python对象到R矩阵的映射  Win10桌面图标出现小盾牌怎么办 Win10去除UAC图标教程【解决】  现代化 SciPy 一维插值:interp1d 的替代方案与最佳实践  迅雷下载到U盘速度很慢怎么办_迅雷U盘下载慢优化方法  解决移动端滚动问题的overflow属性应用指南  MAC如何安全彻底地删除文件_MAC使用终端命令确保文件无法被恢复  taptap防沉迷怎么解除 taptap解除健康系统限制说明【2025最新】  C++如何比较两个字符串_C++ string compare函数与操作符对比  Yandex浏览器官方网页版入口 Yandex浏览器最新版官网  使用Python高效删除Word宏并转换DOCM为DOCX格式  Yandex搜索引擎官网入口_俄罗斯Yandex免登录一键直达  腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程 

搜索