乙個萬用的hashfunction

2022-08-03 07:54:13 字數 2281 閱讀 3363

c++11裡新的容器unorderedmap,其底層是乙個hashtable,在c++98中,unorderedmap其實已經有過,叫做hashmap。

unorderedmap(hashmap)是乙個模板,模板引數有5個,以下是可能的偽**(不同的編譯器有不同的實現)

1 template 

2 classvalue,

3 class hashfcn = hash,

4 class equalkey = equals_to,

5 class alloc = alloc>

6 classhash_map

7 ;

key是鍵值型別,value是實值型別,hashfcn是乙個用來尋找bucket位置的函式,稍後重點講述,equalkey是用來確定兩個物件如何算相等,alloc是記憶體分配相關。

hashtale實際上是由一層vector形成乙個bucket的集合,每個bucket上掛有乙個鍊錶,在不同編譯器下鍊錶實現可能不同。既是所謂的sperate chaning開鏈法,分開鏈結。

乙個元素想要插入到hashtable,必須要算出掛在哪乙個bucket上,再插入到bucket上的鍊錶後端。

計算出插入到哪乙個bucket上的操作,便是hashfunction的工作。

hashmap是通過key來決定乙個元素的在hashtable中的位置的,因此key的型別尤為關鍵。

如果key是乙個簡單的系統型別,比如int,char。那麼stl已經幫我們定義好了對應的hashfunction。

class hashfcn = hash

我們注意到hashfcn模板的預設引數hash,便是stl給我們實現好的hashfunciton。

舉例hashfunction之前,先用講到乙個計算元素在bucket落腳處的函式bkt_num_key

1 size_type bkt_num_key(const key_type& key, size_t n) const

2

stl最終都會走到hash(key)來計算元素的bucket位置。

stl通過偏特化的方式實現了一些簡單型別的hashfunction。舉幾個例子:

1 template  structhash {};

2 3 template<> struct hash

5 };

6 7 template<> struct hash

9 };

那麼其實簡單型別的hashfunction就是返回自己本身。有稍微複雜一些的char*

1 template<> struct hash

3 }4

5 //hash function越亂越好

6 inline size_t __stl_hash_string(const char*s)

7

那麼如果乙個key是自定義的型別,hashfunction應該怎麼做呢。

假定我們的自定義型別如下:

structcustomerinfo

這個自定義結構當成unordermap的key,如果你不定義hashfunction應該是不能過編譯的。

也許你會簡單想乙個hashfunction,三個int分別用stl的hashfunction版本,然後加起來!天才=_=。

1 structhashfunccustomer

2 12 };

能過編譯。但是其實這個hashfunction所造成的碰撞是很多的。hashfunction的目標應該是越散越好,因此雜湊表又叫雜湊表。

碰撞的時候,新加的元素會掛在bucket碰撞位置的鍊錶後面。hashtable的查詢複雜度應該是o(1)~o(n),明顯碰撞越多複雜度越趨近於o(n)。

tr1版本(簡單理解成c++98和c++11之間的過渡版本)提供了一種萬用的hashfunction,外層呼叫如下即可:

1 structhashfunccustomer

2 10 };

內部的實現其實並不重要,內部的實現是個數學問題=_=。這裡面內部用了**分割比例,移位等各種操作。

另外乙個版本,我在實際專案中使用過的乙個版本:

1 structhashfunccustomer

2 12 };

僅供參考。

hashfunction怎麼寫的好,應該是個數學問題。

用萬用表如何量測電池的好壞

同問 用萬用表如何量測電池的好壞 2008 10 19 19 57 提問者 781833666 瀏覽次數 4014次 我來幫他解答 2008 10 20 14 38 滿意回答 1 用萬用表直流檔大於電池額定電壓的檔位測試。例如 測試乾電池9v,1.5v用dc10v,dc2v檔測試。2 按電池額定電壓...

用萬用表如何量測電池的好壞

同問 用萬用表如何量測電池的好壞 2008 10 19 19 57 提問者 781833666 瀏覽次數 4014次 我來幫他解答 2008 10 20 14 38 滿意回答 1 用萬用表直流檔大於電池額定電壓的檔位測試。例如 測試乾電池9v,1.5v用dc10v,dc2v檔測試。2 按電池額定電壓...

萬用表檢測常用元器件的方法

一.測電阻器 1.把萬用表調的歐姆檔的適當位置 200,2k,20k,200k,2m,20m,200m 2.用兩個錶筆連線到電阻器兩端,應顯示乙個數字,如果顯示0或者顯示的數字不停變動或顯示數字與電阻器的標示值相差很大,則電阻器損壞.二.測電容器 1.把萬用表調到歐姆檔適當位置 當電容容量 1微法時...