博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ map和unordered_map自定义key
阅读量:6309 次
发布时间:2019-06-22

本文共 2703 字,大约阅读时间需要 9 分钟。

  hot3.png

一、map

1)最简单的方法就是实现该自定义类型的<操作符,代码如下:

class Foo{public:    Foo(int num_)        : num(num_)    {    }    bool operator < (const Foo & cmp) const    {        return num < cmp.num;    }      int num;   };

之后就可以使用Foo作为map的key了:

map
dict;dict[Foo(1)] = 1;

2)定义一个比较操作符,使用它作为map的模板参数,代码如下:

typedef std::pair
Foo2;class Foo2Comparator{public:    bool operator()(const Foo2& key1, const Foo2& key2) const    {        if (key1.first < key2.first)        {            return true;        }        else if (key2.first < key1.first)        {            return false;        }        else        {            return key1.second < key2.second;        }    }};

这时候可以使用Foo2作为map的key了:

map
dict2;dict2[Foo2(Foo(1), 100)] = 1;

3)为用户自定义类型特化std::less,代码如下:

namespace std{    template <>    struct less
     : public binary_function
{     bool operator()(const Foo2& key1, const Foo2& key2) const     {         if (key1.first < key2.first)         {             return true;         }         else if (key2.first < key1.first)         {             return false;         }         else         {             return key1.second < key2.second;         }     } };}

使用这种方法,声明map时无需指定比较函数对象,因为默认的比较对象就是std::less<T>

map
dict2;dict2[Foo2(Foo(1), 100)] = 3;

二、unordered_map

        当试图使用自定义类型作为 unordered_map 的键值时,则必须为自定义类型定义 Hash 函数与相等的判断条件。我们先定义自定义类型作键值,代码如下:

struct KEY{	int first;	int second;	int third;	KEY(int f, int s, int t) : first(f), second(s), third(t){}};

1)Hash 函数

        必须为 override 了 operator() 的一个类,一般自定义类型可能包含几种内置类型,我们可以分别计算出内置类型的 Hash Value 然后对它们进行 Combine 得到一个哈希值,一般直接采用移位加异或(XOR)便可得到还不错的哈希值(碰撞不会太频繁),如下:

struct HashFunc{	std::size_t operator()(const KEY &key) const 	{		using std::size_t;		using std::hash;		return ((hash
()(key.first) ^ (hash
()(key.second) << 1)) >> 1) ^ (hash
()(key.third) << 1); }};

2)相等函数

        哈希需要处理碰撞,意味着必须得知道两个自定义类型对象是否相等,所以必须得提供比较相等的方法,可以 重载operator ==,可以用 std::equal,也可以实现一个 重写 operator () 的类,这里我们采用后者,代码如下:

struct EqualKey{	bool operator () (const KEY &lhs, const KEY &rhs) const	{		return lhs.first  == rhs.first			&& lhs.second == rhs.second			&& lhs.third  == rhs.third;	}};

下面为一个具体应用的例子:

int main(){	unordered_map
hashmap = { { { 01, 02, 03 }, "one" }, { { 11, 12, 13 }, "two" }, { { 21, 22, 23 }, "three" }, }; KEY key(11, 12, 13); auto it = hashmap.find(key); if (it != hashmap.end()) { cout << it->second << endl; } return 0;}

参考资料:

http://blog.sina.com.cn/s/blog_48d4cf2d0100mx4t.html

http://www.ithao123.cn/content-10629313.html

转载于:https://my.oschina.net/shou1156226/blog/757568

你可能感兴趣的文章
oracle.jdbc.driver.OracleDriver和oracle.jdbc.OracleDriver这两个驱动的区别
查看>>
NSQ部署
查看>>
git常用命令记录
查看>>
IBM发布新一代云计算工具包MobileFirst Foundation
查看>>
唯品会HDFS性能挑战和优化实践
查看>>
大规模学习该如何权衡得失?解读NeurIPS 2018时间检验奖获奖论文
查看>>
大厂前端高频面试问题与答案精选
查看>>
我们用5分钟写了一个跨多端项目
查看>>
Visual Studio 15.4发布,新增多平台支持
查看>>
有赞透明多级缓存解决方案(TMC)设计思路
查看>>
如何设计高扩展的在线网页制作平台
查看>>
Git 2.5增加了工作树、改进了三角工作流、性能等诸多方面
查看>>
Swift 5将强制执行内存独占访问
查看>>
中台之上(二):为什么业务架构存在20多年,技术人员还觉得它有点虚?
查看>>
深度揭秘腾讯云低功耗广域物联网LPWAN 技术及应用
查看>>
与Jeff Sutherland谈敏捷领导力
查看>>
More than React(四)HTML也可以静态编译?
查看>>
React Native最佳学习模版- F8 App开源了
查看>>
云服务正在吞噬世界!
查看>>
阅读Android源码的一些姿势
查看>>