C++11新增了一类散列容器包括unordered_set, unordered_map, unordered_multiset, unordered_multimap, 即之前熟悉的hash_set, hash_map等。

这类容器底层以哈希表实现之,通过unordered_map介绍下这类容器的使用。

unordered_map 是一个模板类,需要我们提供5个魔板参数。依次为:key值的类型, value值的类型,hash函数, 等价函数, 容器分配器。其中后三个有默认参数,那我们是不是只需要提供前2个模板参数就可以使用了呢? 不一定。当我们使用的key为内置类型时(如int, double, float, string等),后面三个默认模板参数在STL内有其特化版本,故可以直接进行使用。可一旦你的类为自定义类型, 其中的hash和equal就得由你自己提供。其实也不难理解, 假设你的对象是一块石头,石头怎么进行hash, 石头怎么怎么比大小呢?编译器当然不知道,这就需要你告诉编译器。下面我们对这2种情况分别举例说明。

(一)、当key为内置类型:

unordered_map<string, int> m_map;

当key为内置类型, 仅需提供key与value的类型便可运用。 其中hash<string> 与 equal <int> 均有特化版本,分配器对整个容器进行内存管理,这三个参数均为默认参数。

(二)、当key为自定义类型:

  比如我们简单定义一个package类,里面仅有名字,电话2项数据。

class package
{
public:
string getName() const { return name; }
long long getPhone() const { return phone; } package(string m_name = , long long m_pNum = ); bool operator== (const package& p) const
{ return name == p.name &&
phone == p.phone;
} private:
string name;
long long phone;
};

然后将原生hash包装使用下:

namespace std
{
template<>
struct hash<package>
{
size_t operator() (const package& s) const noexcept
{
return hash<decltype(s.getName())>()(s.getName()) +
hash<decltype(s.getPhone())>()(s.getPhone());
}
}; // 间接调用原生Hash.
}

或者可以借助借助boost库的hash_value:

namespace std
{
template<>
struct hash<package>
{
size_t operator() (const package& s) const noexcept
{
auto t = make_tuple(s.getName(), s.getPhone());
size_t value = boost::hash_value(t);
return value; // make_tuple(s.getName(), s.getPhone()) 等价于 tuple<string, long long>()(s.getName(), s.getPhone())
}
}; // 间接调用原生Hash.
}

当我们把Hash函数(package的特化版本)和 等价函数 (操作符==重载)提供后, 便可使用自定义版本的unordered_map了:

unordered_map<package, int> m_map;

下面给出测试代码:

测试环境: VS2017

#include <iostream>
#include <unordered_map>
#include <string>
#include <algorithm>
//#include <boost/functional/hash.hpp> // 根据安装路径选择hash.hpp
#include <tuple> using namespace std; class package
{
public:
string getName() const { return name; }
long long getPhone() const { return phone; } package(string m_name = , long long m_pNum = ); bool operator== (const package& p) const
{ return name == p.name &&
phone == p.phone;
} private:
string name;
long long phone;
}; package::package(string m_name, long long m_pNum)
: name(m_name), phone(m_pNum) { } namespace std
{
template<>
struct hash<package>
{
size_t operator() (const package& s) const noexcept
{
return hash<decltype(s.getName())>()(s.getName()) +
hash<decltype(s.getPhone())>()(s.getPhone()); //auto t = make_tuple(s.getName(), s.getPhone());
//size_t value = boost::hash_value(t);
//return value; // make_tuple(s.getName(), s.getPhone()) 等价于 tuple<string, long long>()(s.getName(), s.getPhone())
}
}; // 间接调用原生Hash.
} int main()
{
unordered_map<package, int> m_map; package p1{ "Wang", };
package p2{ "Li", };
package p3{ "Zhang", };
package p4{ "Zhou", };
package p5{ "Wang", };
package p6{ "Wang", }; m_map[p1]++;
m_map[p2]++;
m_map[p3]++;
m_map[p4]++;
m_map[p5]++;
m_map[p6]++; cout << m_map.bucket(p1) << " ";
cout << m_map.bucket(p2) << " ";
cout << m_map.bucket(p3) << " ";
cout << m_map.bucket(p4) << " ";
cout << m_map.bucket(p5) << " ";
cout << m_map.bucket(p6) << " " << endl; return ;
}

本文转自:https://www.cnblogs.com/xiguas/p/9977933.html

c++ unordered_map 自定义key的更多相关文章

  1. STL: unordered_map 自定义键值使用

    使用Windows下 RECT 类型做unordered_map 键值 1. Hash 函数 计算自定义类型的hash值. struct hash_RECT { size_t operator()(c ...

  2. unorder_map 自定义KEY

    1. boost::unorder_map 实现自定义KEY // boostLibTest.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" ...

  3. zabbix自定义key

    zabbix自定义key 1.修改客户端配置文件 #vi /opt/zabbix/etc/zabbix_agentd.conf Include=/opt/zabbix/etc/zabbix_agent ...

  4. 自学Zabbix3.5.5-监控项item-User parameters(自定义key)

    为什么要自定义KEY,即User parameters功能 有时候我们想让被监控端执行一个zabbix没有预定义的检测,zabbix的用户自定义参数功能提供了这个方法.我们可以在客户端配置文件zabb ...

  5. Zabbix常用key和自定义key的讲解

    zabbix中常用到的几个key: 1.监控端口的:net.tcp.port[,3306],可以在服务器端对被监控端测试. /usr/local/zabbix/bin/ -s192.168.8.120 ...

  6. zabbix使用自定义key进行监控

    我的zabbix-server是安装在另一台虚拟机上的,用来监控下图中的这台虚拟机 先修改zabbix的客户端配置文件,增加UserParameter那行,这里我只是用来测试,所以就随便起了一个名为p ...

  7. zabbix 通过自定义key完成网卡监控

    创建执行脚本: # cat /etc/zabbix/monitor_scripts/network.sh #!/bin/bash #set -x usage() { echo "Useage ...

  8. zabbix 自定义 key (转)

    转自:http://www.cnblogs.com/miclesvic/p/6164303.html 1.在zabbix_agent端zabbix_agentd.conf配置文件中增加自定义Key(/ ...

  9. 监控服务器cpu、磁盘、模板以及自定义key

    一.检测主机存活 net.tcp.service.perf[tcp,,] Float型 返回0代表端口挂了 zabbix fping要开启sudo权限之类比较不方便 二.监控CPU负载 监控load ...

随机推荐

  1. hdu5289 RMQ+二分

    RMQ预处理最大值,最小值,然后对于每一点,二分可能满足的区间长度,长度-1就是该店开始的区间满足的个数. #include<stdio.h> #include<string.h&g ...

  2. @hdu - 6687@ Rikka with Stable Marriage

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个稳定婚姻匹配问题,其中第 i 个男生与第 j 个女生之间 ...

  3. Java面向对象----Java面向对象(OOP)概念

    理解面向对象 关键:让每一个对象负责执行一组相关任务 面向过程:算法第一,数据第二 面向对象:数据第一,算法第一 特点: 万物皆对象 程序是一组对象彼此之间在发送消息 每个对象都有自己的内存占用,可以 ...

  4. lavarel box 地址

    https://atlas.hashicorp.com/laravel/boxes/homestead download URL https://atlas.hashicorp.com/laravel ...

  5. 03搭建docker私有仓库

    搭建docker私仓,可以使用docker官方提供的registry镜像.该镜像目前有2.0,2.3和2.3.1版本.它只与1.6.0以上版本的docker兼容.搭建私仓的步骤如下: 一:无代理.无认 ...

  6. 突然想起一个有趣的问题:FAT32&NTFS?

    在大学的时候老师提过一个有意思的问题4G的程序存储在什么格式以上的电脑? 首先普及一下两种格式的区别 FAT32:此硬盘格式不支持4GB以上大文件,使用32位文件分配表. NTFS:微软最新文件格式, ...

  7. ArcGIS中的连接和关联表

    大多数数据库的设计指导方针都倾向于将数据库组织成多个表 - 每个表关注一个特定的主题 - 而非一个包含所有必要字段的大型表.设置多个表可以避免数据库中的信息发生重复,因为只会将信息在一个表中存储一次. ...

  8. python代码实现树莓派3b+驱动步进电机

    python代码实现树莓派3b+驱动步进电机 之前买了个树莓派,刚买回来那会儿热情高涨,折腾了一段时间,然后就放那吃灰了.前几天忽然想起来这个东西了,决定再玩玩儿,于是就从某宝上购买了一套步进电机.驱 ...

  9. behavior planning——10 behaior planning pseudocode

    One way to implement a transition function is by generating rough trajectories for each accessible & ...

  10. ubuntu14.04本地域名服务器配置

    dnsmasq 1 修改dnsmasq配置文件/etc/dnsmasq.conf # Change this line if you want dns to get its upstream serv ...