class template
unordered_map
template < class Key, //unordered_map::key_type
class T, //unordered_map::mapped_type
class Hash = hash<Key>, // unordered_map::hasher
class Pred =equal_to<Key>, //unordered_map::key_equal
class Alloc = allocator<pair<const Key,T> > // unordered_map::allocator_type
> class unordered_map;
Unordered Map
哈希map是一種關聯容器,通過鍵值和映射值存儲元素。允許根據鍵值快速檢索各個元素。
在unordered_map中,鍵值一般用來唯一辨別元素,而對應的值是一個對象關聯到這個鍵的内容。鍵映射值的類型可能會有所不同。
在内部unordered_map的元素不以鍵值或映射的元素作任何特定的順序排序,其存儲位置取決于哈希值允許直接通過其鍵值為快速通路單個元素(具有恒定平均的平均時間複雜度)。
unordered_map容器比map容器更快地通過鍵值通路他們的單個元素,雖然unordered_map一般都是比map通過其元素的一個子集範圍疊代效率低。
哈希map允許使用操作運算符(運算符[])以其鍵值作為參數直接通路元素。
容器屬性
關聯
在關聯容器的元素通過鍵值引用,而不是由他們在容器中的絕對位置。
無序
無序容器通過哈希表組織其元素的使用,允許通過鍵值快速通路其對應元素。
映射
每個元素關聯到一鍵值對應一映射值:鍵值用于識别元素,其主要内容是鍵對應的值。
唯一鍵
在容器中沒有兩個元素可以有相同的鍵。
配置設定器的喚醒
容器使用一個配置設定器對象動态地處理其存儲需求。
模闆參數
Key
關鍵值的類型。一個unordered_map中的每個元素通過鍵值被唯一辨別。
T
映射值的類型。
一個unordered_map中的每個元素是用來存儲一些資料作為其映射值。别名為成員類型unordered_map:: mapped_type。請注意,這是和unordered_map:: value_type不同的(見下文)。
Hash
學習資料結構的時候 偶然得知有個unordered_map,以前沒有用過,查了查相關内容,據說效率比map高出很多,而且耗資源也少,研究一下
至于具體效率咋樣我就不去驗證了,網上太多了
關鍵是
unordered_map與map的差別
boost::unordered_map, 它與 stl::map的差別就是,stl::map是按照operator<比較判斷元素是否相同,以及比較元素的大小,然後選擇合适的位置插入到樹中。是以,如果對map進行周遊(中序周遊)的話,輸出的結果是有序的。順序就是按照operator< 定義的大小排序。
而boost::unordered_map是計算元素的Hash值,根據Hash值判斷元素是否相同。是以,對unordered_map進行周遊,結果是無序的。
用法的差別就是,stl::map 的key需要定義operator< 。 而boost::unordered_map需要定義hash_value函數并且重載operator==。對于内置類型,如string,這些都不用操心。對于自定義的類型做key,就需要自己重載operator== 或者hash_value()了。
最後,說,當不需要結果排好序時,最好用unordered_map。
Linux下使用
普通的key就不說了和map一樣
看一下用sockaddr_in 作為key的方法
[cpp]
view plain
copy
- <span style="font-family:Microsoft YaHei;font-size:18px;">#ifndef CSESSION_H
- #define CSESSION_H
- #include <netinet/in.h>
- #include <time.h>
- #include <map>
- #include <string.h>
- #include <tr1/unordered_map> //頭檔案
- #include <iostream>
- using namespace std;
- using namespace std::tr1;
- struct Terminal
- {
- int nid ; //id the key for terminal
- //ip the key for Client
- time_t tm; //last alive time
- //status
- Terminal();
- ~Terminal();
- const Terminal& term);
- };
- struct hash_func //hash 函數
- {
- size_t operator()(const sockaddr_in &addr) const
- {
- return addr.sin_port*9999 + addr.sin_addr.s_addr;
- }
- };
- struct cmp_fun //比較函數 ==
- {
- bool operator()(const sockaddr_in &addr1, const sockaddr_in &addr2) const
- {
- return memcmp(&addr1, &addr2, sizeof(sockaddr_in)) == 0 ? true:false;
- }
- };
- //typedef unordered_map<int,Terminal*> MapTerminal; // Terminal socket 作為key
- //typedef unordered_map<int,Terminal*>::iterator MapTerminal_It; //
- typedef unordered_map<sockaddr_in, Terminal*,hash_func, cmp_fun> MapClientSession; // sockaddr_in作為key
- typedef unordered_map<sockaddr_in, Terminal*,hash_func, cmp_fun>::iterator MapClientSession_It; //
- #endif // CSESSION_H</span>
operator== 有兩種方式
一種是
struct st
{
bool operator==(const st &s) const
...
};
另一種就是自定義函數體,代碼中
struct cmp_fun
{
bool operator()(...)
...
}
必須要自定義operator==和hash_value。 重載operator==是因為,如果兩個元素的hash_value的值相同,并不能斷定這兩個元素就相同,必須再調用operator==。 當然,如果hash_value的值不同,就不需要調用operator==了。