unordered_map 性能優化 與 重載

參考:stl中unordered_map的insert/clear 性能問題解決
參考:關於map和unorderd_map的使用


insert / clear 性能優化

當插入元素過多時,發生了哈希碰撞,碰撞開鏈到一定的閾值,觸發了增加 bucketbucket,進而觸發了 rehashrehash

因此,reservereserve 可以用來預留元素個數,rehashrehash 根據提供的元素個數預留足夠的bucket數目

unordered_map <int, int> mp;
mp.reserve(2e7);
mp.rehash(2e7); 

同時,unordered_mapunordered\_map 每清空一次會遍歷刪除所有內容,可以替換爲 swapswap

unordered_map <int, int> mp1;
mp.swap(mp1);

時間複雜度即可降爲 O(1)O(1)


重載

unordered_mapunordered\_map 是哈希表的機制,也就是每個 keykey 會生成一個哈希碼,根據哈希碼來判斷元素是否相同,故必須提供產生哈希碼的函數,但是哈希碼相同並不一定代表兩個元素相同,所以還要實現 ==== 操作符。

以下用三種方式重寫哈希:
①:手動重寫
②:調用 boostboost 庫函數(要手動下載 boostboost 庫)
③:簡單哈希

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;

//#include <functional>
// from boost (functional/hash):
// see http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html template
template <typename T>
inline void hash_combine(std::size_t &seed, const T &val) {
    seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
// auxiliary generic functions to create a hash value using a seed
template <typename T> inline void hash_val(std::size_t &seed, const T &val) {
    hash_combine(seed, val);
}
template <typename T, typename... Types>
inline void hash_val(std::size_t &seed, const T &val, const Types &... args) {
    hash_combine(seed, val);
    hash_val(seed, args...);
}

template <typename... Types>
inline std::size_t hash_val(const Types &... args) {
    std::size_t seed = 0;
    hash_val(seed, args...);
    return seed;
}


struct node {
	string str;
	int num;
	node(string _str, int _num):str(_str), num(_num) {}
	bool operator == (const node &A) const {
		return (str==A.str && num==A.num);
	}
};
struct node_hash {
	size_t operator() (const node &A) const {
		return hash_val(A.str, A.num);
//	    using boost::hash_value;
//	    using boost::hash_combine;
//		size_t seed = 0;
//		hash_combine(seed, hash_value(A.str));
//		hash_combine(seed, hash_value(A.num));
//		return seed;
		
//		return hash<string>()(A.str) ^ hash<int>()(A.num);
	}
};
unordered_map <node, int, node_hash> mp;


signed main() {
	mp[node("wpf", 666)] = 11;
	mp[node("zzz", 123)] = 22;
	printf("%d\n", (*mp.begin()).first.num);
	printf("%d\n", (*mp.begin()).second);

	deb(mp[node("zzz", 123)]);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章