C++中无序容器自定义hash函数的写法

声明方式、常用函数、复杂度

Posted by AspenStars on March 21, 2020

基本介绍

C++11添加了unordered_setunodered_map两种无序容器,这种容器的内部实现是基于hash的,不同于基于红黑树实现的set和map。

STL为我们提供了基本数据类型、string类型等的hash函数, 包括:bool、char、unsigned char、wchar_t、char16_t、char32_t、short、int、long、long long、unsigned short、unsigned int、unsigned long、unsigned long long、float、double、long double

实例

本文以unordered_set<std::pair<int, int>>为例,讲述如何为类型自定义哈希函数。

std::unordered_set 类的声明

1
2
3
4
5
template < class Key, // unordered_set::key_type/value_type >
           class Hash = hash<Key>,           // unordered_set::hasher
           class Pred = equal_to<Key>,       // unordered_set::key_equal
           class Alloc = allocator<Key>      // unordered_set::allocator_type
           > class unordered_set;

第二个模板参数就是与哈希函数相关的内容,不过它并不是接收一个函数,而是一个函数对象,因此我们可以实现一个计算pair<int, int>的函数对象

1、第一种写法:

1
2
3
4
5
6
class myhash{
    public:
    std::size_t operator()(const std::pair<int, int> p) const{
        return std::hash<int>()(p.first) ^ std::hash<int>()(p.second);
    }
};

2、第二种写法:lambda函数的形式

1
auto hash_function = [](const pair<int, int>& p) {return hash<int>()(p.first) ^ hash<int>()(p.second);};

如果引用了std名称空间,上面也可以去掉std:: 上述例子中使用pair 中两个元素的哈希值的异或作为std::pair的哈希值,你可以采用任何你可以想到的方法构造哈希值,只要返回结果为std::size_t 即可

这样就能对pair类型使用unoreder_set了

1
unordered_set<pair<int,int>, myhash> us;

参考资料

  1. kedixa的博客 - unordered_set/map自定义哈希函数
  2. tiny丶 - C++ STL 之 unordered_set 介绍