詳細介紹C++STL:unordered_map

不得不提一下,hash_map未加入在C++11標準中。java

在VC中編譯: ios

1 #include <hash_map>
2 using namespace stdext;
3 hash_map<int ,int> myhash;

 在GCC中編譯:c++

1 #include <ext/hash_map>
2 using namespace __gnu_cxx;
3 hash_map<int ,int> myhash;

既如此,仍是用unordered_map吧!數組

 

C++ 11標準中加入了unordered系列的容器。unordered_map記錄元素的hash值,根據hash值判斷元素是否相同。map至關於java中的TreeMap,unordered_map至關於HashMap。不管從查找、插入上來講,unordered_map的效率都優於hash_map,更優於map;而空間複雜度方面,hash_map最低,unordered_map次之,map最大。app

unordered_map與map的對比:函數

  存儲時是根據key的hash值判斷元素是否相同,即unordered_map內部元素是無序的,而map中的元素是按照二叉搜索樹存儲(用紅黑樹實現),進行中序遍歷會獲得有序遍歷。因此使用時map的key須要定義operator<。而unordered_map須要定義hash_value函數而且重載operator==。可是不少系統內置的數據類型都自帶這些。ui

  總結:結構體用map重載<運算符,結構體用unordered_map重載==運算符。spa

unordered_map與hash_map對比:指針

  unordered_map原來屬於boost分支和std::tr1中,而hash_map屬於非標準容器。
  unordered_map感受速度和hash_map差很少,可是支持string作key,也能夠使用複雜的對象做爲key。
  unordered_map編譯時gxx須要添加編譯選項:--std=c++11c++11

unordered_map模板: 

1 template < class Key,                                    // unordered_map::key_type
2            class T,                                      // unordered_map::mapped_type
3            class Hash = hash<Key>,                       // unordered_map::hasher
4            class Pred = equal_to<Key>,                   // unordered_map::key_equal
5            class Alloc = allocator< pair<const Key,T> >  // unordered_map::allocator_type
6            > class unordered_map;

 迭代器:

unordered_map的迭代器是一個指針,指向這個元素,經過迭代器來取得它的值。

1 unordered_map<Key,T>::iterator it;
2 (*it).first;             // the key value (of type Key)
3 (*it).second;            // the mapped value (of type T)
4 (*it);                   // the "element value" (of type pair<const Key,T>) 

它的鍵值分別是迭代器的first和second屬性。 

1 it->first;               // same as (*it).first   (the key value)
2 it->second;              // same as (*it).second  (the mapped value) 

成員函數:

=================迭代器========================= 
begin   返回指向容器起始位置的迭代器(iterator) 
end      返回指向容器末尾位置的迭代器 
cbegin    返回指向容器起始位置的常迭代器(const_iterator) 
cend    返回指向容器末尾位置的常迭代器 
=================Capacity================ 
size     返回有效元素個數 
max_size  返回 unordered_map 支持的最大元素個數 
empty        判斷是否爲空 
=================元素訪問================= 
operator[]       訪問元素 
at         訪問元素 
=================元素修改================= 
insert    插入元素 
erase   刪除元素 
swap    交換內容 
clear     清空內容 
emplace  構造及插入一個元素 
emplace_hint 按提示構造及插入一個元素 
================操做========================= 
find       經過給定主鍵查找元素,沒找到:返回unordered_map::end
count      返回匹配給定主鍵的元素的個數 
equal_range   返回值匹配給定搜索值的元素組成的範圍 
================Buckets====================== 
bucket_count    返回槽(Bucket)數 
max_bucket_count    返回最大槽數 
bucket_size       返回槽大小 
bucket       返回元素所在槽的序號 
load_factor     返回載入因子,即一個元素槽(Bucket)的最大元素數 
max_load_factor    返回或設置最大載入因子 
rehash       設置槽數 
reserve        請求改變容器容量

 插入元素示例:

 1 // unordered_map::insert
 2 #include <iostream>
 3 #include <string>
 4 #include <unordered_map>
 5 using namespace std;
 6 
 7 void display(unordered_map<string,double> myrecipe,string str)
 8 {
 9     cout << str << endl;
10     for (auto& x: myrecipe)
11         cout << x.first << ": " << x.second << endl;
12     cout << endl;
13 }
14 
15 int main ()
16 {
17     unordered_map<string,double>
18     myrecipe,
19     mypantry = {{"milk",2.0},{"flour",1.5}};
20 
21     /****************插入*****************/
22     pair<string,double> myshopping ("baking powder",0.3);
23     myrecipe.insert (myshopping);                        // 複製插入
24     myrecipe.insert (make_pair<string,double>("eggs",6.0)); // 移動插入
25     myrecipe.insert (mypantry.begin(), mypantry.end());  // 範圍插入
26     myrecipe.insert ({{"sugar",0.8},{"salt",0.1}});    // 初始化數組插入(能夠用二維一次插入多個元素,也能夠用一維插入一個元素)
27     myrecipe["coffee"] = 10.0;  //數組形式插入
28 
29     display(myrecipe,"myrecipe contains:");
30 
31     /****************查找*****************/
32     unordered_map<string,double>::const_iterator got = myrecipe.find ("coffee");
33 
34     if ( got == myrecipe.end() )
35         cout << "not found";
36     else
37         cout << "found "<<got->first << " is " << got->second<<"\n\n";
38     /****************修改*****************/
39     myrecipe.at("coffee") = 9.0;
40     myrecipe["milk"] = 3.0;
41     display(myrecipe,"After modify myrecipe contains:");
42 
43 
44     /****************擦除*****************/
45     myrecipe.erase(myrecipe.begin());  //經過位置
46     myrecipe.erase("milk");    //經過key
47     display(myrecipe,"After erase myrecipe contains:");
48 
49     /****************交換*****************/
50     myrecipe.swap(mypantry);
51     display(myrecipe,"After swap with mypantry, myrecipe contains:");
52 
53     /****************清空*****************/
54     myrecipe.clear();
55     display(myrecipe,"After clear, myrecipe contains:");
56     return 0;
57 }
58 /*
59 myrecipe contains:
60 salt: 0.1
61 milk: 2
62 flour: 1.5
63 coffee: 10
64 eggs: 6
65 sugar: 0.8
66 baking powder: 0.3
67 
68 found coffee is 10
69 
70 After modify myrecipe contains:
71 salt: 0.1
72 milk: 3
73 flour: 1.5
74 coffee: 9
75 eggs: 6
76 sugar: 0.8
77 baking powder: 0.3
78 
79 After erase myrecipe contains:
80 flour: 1.5
81 coffee: 9
82 eggs: 6
83 sugar: 0.8
84 baking powder: 0.3
85 
86 After swap with mypantry, myrecipe contains:
87 flour: 1.5
88 milk: 2
89 
90 After clear, myrecipe contains:
91 */

遍歷示例:

 1 // unordered_map::bucket_count
 2 #include <iostream>
 3 #include <string>
 4 #include <unordered_map>
 5 using namespace std;
 6 
 7 int main ()
 8 {
 9     unordered_map<string,string> mymap =
10     {
11         {"house","maison"},
12         {"apple","pomme"},
13         {"tree","arbre"},
14         {"book","livre"},
15         {"door","porte"},
16         {"grapefruit","pamplemousse"}
17     };
18     /************begin和end迭代器***************/
19     cout << "mymap contains:";
20     for ( auto it = mymap.begin(); it != mymap.end(); ++it )
21         cout << " " << it->first << ":" << it->second;
22     cout << endl;
23     /************bucket操做***************/
24      unsigned n = mymap.bucket_count();
25 
26     cout << "mymap has " << n << " buckets.\n";
27 
28     for (unsigned i=0; i<n; ++i)
29     {
30         cout << "bucket #" << i << "'s size:"<<mymap.bucket_size(i)<<" contains: ";
31         for (auto it = mymap.begin(i); it!=mymap.end(i); ++it)
32             cout << "[" << it->first << ":" << it->second << "] ";
33         cout << "\n";
34     }
35 
36     cout <<"\nkey:'apple' is in bucket #" << mymap.bucket("apple") <<endl;
37     cout <<"\nkey:'computer' is in bucket #" << mymap.bucket("computer") <<endl;
38 
39     return 0;
40 }
41 /*
42 mymap contains: door:porte grapefruit:pamplemousse tree:arbre apple:pomme book:livre house:maison
43 mymap has 7 buckets.
44 bucket #0's size:2 contains: [book:livre] [house:maison]
45 bucket #1's size:0 contains:
46 bucket #2's size:0 contains:
47 bucket #3's size:2 contains: [grapefruit:pamplemousse] [tree:arbre]
48 bucket #4's size:0 contains:
49 bucket #5's size:1 contains: [apple:pomme]
50 bucket #6's size:1 contains: [door:porte]
51 
52 key:'apple' is in bucket #5
53 
54 key:'computer' is in bucket #6
55 */
相關文章
相關標籤/搜索