c++ unordered_map/set自定義物件的hash
平時很少用到unordered_set的自定義物件,常用的都是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/c++ 標準庫 set 自定義關鍵字型別與比較函式C++型別函式
- 自定義許可權物件物件
- AXIS - 傳遞自定義物件物件
- NSUserDefault 儲存自定義物件物件
- 自定義物件池實踐物件
- c++ map和unordered_map比較C++
- SAP自定義許可權物件物件
- 自定義事件相容處理物件事件物件
- 例說資料結構&STL(十一)——hash_map/unordered_map資料結構
- Rust引用自定義c/c++庫RustC++
- Service或自定義物件使用LiveData物件LiveData
- 巧用GenericObjectPool建立自定義物件池Object物件
- 集合框架-去重自定義物件案例框架物件
- [C++] 自定義C++比較器比較大小C++
- Eloquent ORM 自定義 builder——實現 find_in_set 查詢ORMUI
- C/C++ Qt TableDelegate 自定義代理元件C++QT元件
- C++:使自定義類支援迭代器C++
- JavaScript Set物件JavaScript物件
- 集合框架-ArrayList集合儲存自定義物件的排序案例框架物件排序
- iOS中對NSArray中自定義的物件進行排序iOS物件排序
- C++ set and multisetC++
- C++ Qt開發:QItemDelegate 自定義代理元件C++QT元件
- 例說資料結構&STL(十)——hash_set/unordered_set資料結構
- 《STL原始碼剖析》-- stl_hash_set.h原始碼
- 物件導向 約束、自定義異常、加密物件加密
- webService學習(二)—— 呼叫自定義物件引數Web物件
- Python 3.x自定義迭代器物件Python物件
- 自定義物件封裝資料警告解決物件封裝
- 自定義物件池在 Caffeine 框架中實踐物件框架
- 關於c++ STL map 和 unordered_map 的效率的對比測試C++
- 工廠模式建立物件和自定義建構函式建立物件的異同模式物件函式
- 如何用Map物件建立Set物件物件
- 如何在Kubernetes 裡新增自定義的 API 物件(一)API物件
- .NET 中Newtonsoft的使用 自定義物件的序列化物件
- C++編寫自定義TCP包併傳送C++TCP
- ROS2/C++ 自定義訊息型別ROSC++型別
- 關於C++類的定義和物件的建立詳解C++物件
- 【C++ STL】Set用法C++