c++ unordered_map/set自定义对象的hash
2017-01-11 16:39
441 查看
平时很少用到unordered_set的自定义对象,常用的都是
unordered_map/set是采用hash散列进行存储的,因此存储的对象必须提供两个方法,1,hash告知此容器如何生成hash的值,2,equal_to 告知容器当出现hash冲突的时候,如何区分hash值相同的不同对象
假定要存储的对象的类名为Object,则具体有4种方案:
1,定义两个函数对象ObjectHash,以及ObjectEqu,分别实现对Object进行hash,以及比较两个对象是否相同
2,定义两个普通的c类型的函数,实现hahs以及对象比较,与1不同的是,普通函数在构建unordered_map/set的时候,需要decltype来减少显示声明它的类型(当前可以手动指定类型,很长)
例如:
3,定义两个lambda表达式(仿函数),与2类似
4,对Object对象进行模板特化
具体代码如下:
unordered_map<int>, unordered_map<string>之类的内建数据类型。前段时间在写一个编码库的时候,用到了自定义对象,却无从下手,在此对其进行总结。
unordered_map/set是采用hash散列进行存储的,因此存储的对象必须提供两个方法,1,hash告知此容器如何生成hash的值,2,equal_to 告知容器当出现hash冲突的时候,如何区分hash值相同的不同对象
假定要存储的对象的类名为Object,则具体有4种方案:
1,定义两个函数对象ObjectHash,以及ObjectEqu,分别实现对Object进行hash,以及比较两个对象是否相同
2,定义两个普通的c类型的函数,实现hahs以及对象比较,与1不同的是,普通函数在构建unordered_map/set的时候,需要decltype来减少显示声明它的类型(当前可以手动指定类型,很长)
例如:
std::function<size_t(const Object&)>说明hash类型,或者
std::function<bool (const Object&, const Object&)>说明比较类型
3,定义两个lambda表达式(仿函数),与2类似
4,对Object对象进行模板特化
具体代码如下:
#include <iostream> #include <sstream> #include <string> #include <vector> #include <list> #include <stack> #include <queue> #include <algorithm> #include <map> #include <set> #include <unordered_map> #include <unordered_set> #include <iomanip> #include <cstring> #include <cmath> #include <cstdlib> #include <cstdio> using namespace std; //改变这个启用不同的hash方案 #define RECORD_NAMESPACE struct Record { string name; int val; }; #ifdef RECORD_FUNCTION_OBJECT struct RecordHash { size_t operator()(const Record& rhs) const{ return hash<string>()(rhs.name) ^ hash<int>()(rhs.val); } }; struct RecordCmp { bool operator()(const Record& lhs, const Record& rhs) const{ return lhs.name == rhs.name && lhs.val == rhs.val; } }; unordered_set<Record, RecordHash, RecordCmp> records = { { "b", 100 }, { "a", 80 }, { "cc", 70 }, { "d", 60 }, { "d", 60 } }; #endif//RECORD_FUNCTION_OBJECT #ifdef RECORD_C_FUNCTION size_t RecordHash(const Record& rhs){ return hash<string>()(rhs.name) ^ hash<int>()(rhs.val); } bool RecordCmp(const Record& lhs, const Record& rhs){ return lhs.name == rhs.name && lhs.val == rhs.val; } //直接使用成员初始化列表,vs2013不能编译通过 unordered_set<Record, decltype(&RecordHash), decltype(&RecordCmp)> records = { 10, RecordHash, RecordCmp }; struct RunBeforeMain { RunBeforeMain(){ records.insert({ "a", 100 }); } }; static RunBeforeMain dummyObject; #endif //RECORD_C_FUNCTION #ifdef RECORD_LAMBDA //直接使用auto RecordHash不能编译通过,vs2013 auto &RecordHash = [](const Record& rhs){ return hash<string>()(rhs.name) ^ hash<int>()(rhs.val); }; auto &RecordCmp = [](const Record& lhs, const Record& rhs){ return lhs.name == rhs.name && lhs.val == rhs.val; }; unordered_set<Record, decltype(RecordHash), decltype(RecordCmp)> records = { 10, RecordHash, RecordCmp }; struct RunBeforeMain { RunBeforeMain(){ records.insert({ "a", 100 }); } }; static RunBeforeMain dummyObject; #endif//RECORD_LAMBDA #ifdef RECORD_NAMESPACE namespace std{ template<> struct hash<Record> { size_t operator()(const Record& rhs) const{ return hash<string>()(rhs.name) ^ hash<int>()(rhs.val); } }; template<> struct equal_to < Record > { bool operator()(const Record& lhs, const Record& rhs) const{ return lhs.name == rhs.name && lhs.val == rhs.val; } }; } unordered_set<Record> records = { { "b", 100 }, { "a", 80 }, { "cc", 70 }, { "d", 60 }, { "d", 60 } }; #endif //RECORD_NAMESPACE int main() { auto showRecords = [](){ for (auto i : records) { cout << "{" << i.name << "," << i.val << "}" << endl; } }; showRecords(); return 0; }
相关文章推荐
- 【C++】【总结】unordered_map,unordered_set,map和set的用法和区别
- 【c++】unordered_set和unordered_map
- c++的multimap(set)和unordered_map(set)
- C++ unordered_map 自定义key
- hash_map vs unordered_map vs map vs unordered_set
- C++ unordered_map自定义KEY用法以及insert无法覆盖解决办法
- map unordered_map hash_map比一比
- 利用unordered_map代替hash_map - My Study
- C++中的哈希容器unordered_map使用示例
- hash_set和hash_map自定义数据类型的处理
- Linux下map hash_map和unordered_map效率比较
- C++中map、hash_map、unordered_map、unordered_set通俗辨析
- Java基础知识强化之集合框架笔记40:Set集合之HashSet存储自定义对象并遍历
- STL set multiset map multimap unordered_set unordered_map example
- unordered_map map hash_map
- hash_map/unordered_map原理和使用整理
- STL容器分析--unordered_map/unordered_set(C++11)
- Linux下map hash_map和unordered_map效率比较
- c++ map hash_map unordered_map 比较
- C++中map、hash_map、unordered_map、unordered_set通俗辨析