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. json,pickle模块

    序列化 把对象从内存中编成可储存或传输的过程称之为序列化,输出为json串,.json文件 反序列化 把json串反编成Python数据类型 json模块 用于跨平台交互 json模块下不可转换集合( ...

  2. C#面向对象基础 —— 类与对象

    文章来源: https://www.cnblogs.com/huluobozu/p/5070500.html 一.类与对象 类是面向对象编程的基本单元:类造出来的变量叫对象. 一个类包含俩种成员:字段 ...

  3. 2016 Asia Jakarta Regional Contest L - Tale of a Happy Man UVALive - 7722

    UVALive - 7722 一定要自己做出来!

  4. C# 从零开始写 SharpDx 应用 初始化dx修改颜色

    原文:C# 从零开始写 SharpDx 应用 初始化dx修改颜色 版权声明:博客已迁移到 https://blog.lindexi.com 欢迎访问.如果当前博客图片看不到,请到 https://bl ...

  5. MongoDB -- JAVA基本API操作

    package com.example.mongodb.mongodb.demo; import com.mongodb.MongoClient; import com.mongodb.client. ...

  6. 《C语言深度解剖》学习笔记之预处理

    第3章 预处理 1.下面两行代码都是错的.因为注释先于预处理指令被处理,当这两行被展开成“//……”和“/*……*/”时,注释已处理完毕,所以出现错误 #define BSC // #define B ...

  7. CentOs7 使用iptables开启关闭端口

    介绍 iptables命令是Linux上常用的防火墙软件,是netfilter项目的一部分 iptables文件设置路径:命令:vim /etc/sysconfig/iptables-config 注 ...

  8. 基于LIVE555的RTSP QoS实现

    如何从OnDemandServerMediaSubsession类以及继承类对象中获取RTCP信息(句柄) OnDemandServerMediaSubsession.cpp void StreamS ...

  9. Oracle/PLSQL存储过程详解

    原文链接:https://blog.csdn.net/zezezuiaiya/article/details/79557621 Oracle/PLSQL存储过程详解 2018-03-14 17:31: ...

  10. Project Euler Problem 14-Longest Collatz sequence

    记忆化搜索来一发.没想到中间会爆int #include <bits/stdc++.h> using namespace std; const int MAXN = 1000000; in ...