unordered_map 自定义哈希

unordered_map定义

template<class Key,
    class Ty,
    class Hash = std::hash<Key>,
    class Pred = std::equal_to<Key>,
    class Alloc = std::allocator<std::pair<const Key, Ty> > >
    class unordered_map;
    > class unordered_map
  • 第1个参数,存储key值。

  • 第2个参数,存储mapped value。

  • 第3个参数,为哈希函数的函数对象。它将key作为参数,并利用函数对象中的哈希函数返回类型为size_t的唯一哈希值。默认值为std::hash< key>。

  • 第4个参数,为等比函数的函数对象。它内部通过等比操作符’=='来判断两个key是否相等,返回值为bool类型。默认值是std::equal_to< key>。

原理分析

对于unordered_map而言,当我们插入<key, value>的时候,需要哈希函数的函数对象对key进行hash,又要利用等比函数的函数对象确保插入的键值对没有重复。然而,当我们自定义类型时,c++标准库并没有对应的哈希函数和等比函数的函数对象。因此需要分别对它们进行定义。

因为都是函数对象,它们两个的实际定义方法并没有很大差别。不过后者比前者多了一个方法。因为等比函数的函数对象默认值std::equal_to<key>内部是通过调用操作符"=="进行等值判断,因此我们可以直接在自定义类里面进行operator==()重载(成员和友元都可以)。

因此,如果要将自定义类型作为unordered_map的键值,需如下两个步骤:

  1. 定义自定义key的哈希函数的函数对象;

  2. 定义等比函数的函数对象或者在自定义类里重载operator==()。

【PS】如果自定义类的数据成员为私有,则哈希函数对象需要被声明为自定义类的友元。

方法

#include <bits/stdc++.h>
using namespace std;

class Person {
public:
    string name;
    int age;
	friend struct hash_name;//应对成员变量为私有情况
    Person(string n, int a) {
        name = n;
        age = a;
    }

    bool operator==(const Person& p) const {
        return name == p.name && age == p.age;
    }
};

struct hash_name {//公有成员
    size_t operator()(const Person& p) const {//别忘记const
        return hash<string>()(p.name) ^ hash<int>()(p.age);
    }
};
struct equal_person{
    bool operator()(const Person&a,const Person&b) const{
        return a.name==b.name && a.age==b.age;
    }
};

int main() {
    unordered_map<Person, int, hash_name> ids;  
    unordered_map<Person, int, hash_name,equal_person> ids;  //不需要重载operator==写法
    ids[Person("Mark", 17)] = 40561;
    ids[Person("Andrew", 16)] = 40562;
    for (auto ii = ids.begin(); ii != ids.end(); ii++)
        cout << ii->first.name << " " << ii->first.age << " : " << ii->second
             << endl;
    getchar();
    return 0;
}


hash<T>

STL库的哈希函数对象除了字符串类型外只是返回原值,不适用于任何情况,有时需要自己定义哈希函数。

#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); }            \
    };

字符串类型:
在这里插入图片描述

转自:
https://blog.csdn.net/y109y/article/details/82669620

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值