unordered_map的定義
template < class Key,
class T,
class Hash = hash<Key>,
class Pred = equal_to<Key>,
class Alloc = allocator< pair<const Key,T> >> class unordered_map;
- 1
- 2
- 3
- 4
- 5
模版參數說明:
Key
主鍵的類型。
在類模板內部,使用其別名爲 key_type 的成員類型。
T
被映射的值的類型。
在類模板內部,使用其別名爲 mapped_type 的成員類型。
Hash
一元謂詞,以一個 Key 類型的對象爲參數,返回一個基於該對象的 size_t 類型的唯一值。可以是函數指針(Function pointer)類型或函數對象(Function object)類型。在類模板內部,使用其別名爲 hasher 的成員類型。
Pred
二元謂詞,以兩個 Key 類型的對象爲參數,返回一個 bool 值,如果第一個參數等價於第二個參數,該 bool 值爲 true,否則爲 false。默認爲 std::equal_to.可以是函數指針類型(Function pointer)類型或函數對象(Function object)類型.在類模板內部,使用其別名爲 key_equal 的成員類型。
Alloc
容器內部用來管理內存分配及釋放的內存分配器的類型。這個參數是可選的,它的默認值是 std::allocator,這個是一個最簡單的非值依賴的(Value-independent)內存分配器。在類模板內部,使用其別名爲 allocator_type 的成員類型。
特點
unordered_map是一個關聯容器,存儲key,value.其中元素並沒有特別的次序關係
特點:
1. 關聯容器中的元素是通過主鍵(Key)而不是它們在容器中的絕對位置來引用的。
2. 無序(Unordered)無序容器通過 hash 表來組織它們的元素,允許通過主鍵快速地訪問元素。
3. 映射(Map)每個元素爲一個值(Mapped value)綁定一個鍵(Key):以主鍵來標誌主要內容等於被映射值的元素。
4. 鍵唯一(Unique keys)容器中不存在兩個元素有相同的主鍵。
5. 能夠感知內存分配器的(Allocator-aware)容器使用一個內存分配器對象來動態地處理它的存儲需求。
在 unordered_map 內部,元素不會按任何順序排序,而是通過主鍵的 hash 值將元素分組放置到
各個槽(Bucket,也可譯成“桶”)中,這樣就能通過主鍵快速地訪問各個對應的元素
(平均耗時爲一個常量,即時間複雜度爲 O(1))。
成員函數
=================迭代器=========================
begin 返回指向容器起始位置的迭代器(iterator)
end 返回指向容器末尾位置的迭代器
cbegin 返回指向容器起始位置的常迭代器(const_iterator)
cend 返回指向容器末尾位置的常迭代器
=================Capacity================
size 返回有效元素個數
max_size 返回 unordered_map 支持的最大元素個數
empty 判斷是否爲空
=================元素訪問=================
operator[] 訪問元素
at 訪問元素
=================元素修改=================
insert 插入元素
erase 刪除元素
swap 交換內容
clear 清空內容
emplace 構造及插入一個元素
emplace_hint 按提示構造及插入一個元素
================操作=========================
find 通過給定主鍵查找元素
count 返回匹配給定主鍵的元素的個數
equal_range 返回值匹配給定搜索值的元素組成的範圍
================Buckets======================
bucket_count 返回槽(Bucket)數
max_bucket_count 返回最大槽數
bucket_size 返回槽大小
bucket 返回元素所在槽的序號
load_factor 返回載入因子,即一個元素槽(Bucket)的最大元素數
max_load_factor 返回或設置最大載入因子
rehash 設置槽數
reserve 請求改變容器容量
測試
#include <unordered_map>
#include <iostream>
#include <string>
using namespace std;
void PrintIntDoubleUnOrderedMap(unordered_map<int, double>& m, char* pre)
{
unordered_map<int, double>::iterator iter;
cout << pre;
for (iter = m.begin(); iter != m.end(); ++iter)
cout << "(" << iter->first << ", " << iter->second << ")" << " ";
cout << endl;
}
void UnOrderedMapExp1()
{
unordered_map<int, double> m;
//沒有key,就自動創建
m[0] = 1.11;
//普通插入,使用類型轉換
m.insert(unordered_map<int, double>::value_type(1, 2.22));
//帶暗示的插入,pair<int, double>就相當於上面的unordered_map<int ,double>
m.insert(m.end(), pair<int, double>(2, 3.33));
PrintIntDoubleUnOrderedMap(m, "插入元素之前的m:");
//插入一個範圍
unordered_map<int, double> m2;
m2.insert(unordered_map<int, double>::value_type(3, 4.44));
m2.insert(unordered_map<int, double>::value_type(4, 5.44));
m2.insert(unordered_map<int, double>::value_type(5, 6.44));
m.insert(m2.begin(), m2.end());
m.emplace(6, 5.55);
m.emplace_hint(m.end(), 7, 3.09);
m.at(5) = 3.333333;
PrintIntDoubleUnOrderedMap(m, "插入元素之後m:");
unordered_map<int, double>::iterator iter;
iter = m.find(4);
if (iter != m.end())
{
cout << "m.find(4): ";
cout << "(" << iter->first << ", " << iter->second << ")" << endl;
}
if (iter != m.end())
{
m.erase(iter);
}
PrintIntDoubleUnOrderedMap(m, "刪除主鍵爲4的元素之後m:");
//遍歷刪除
for (iter = m.begin(); iter != m.end(); ++iter)
{
if (iter->first == 2)
{
m.erase(iter);
break;
}
}
//內部數據
cout << "bucket_count:" << m.bucket_count() << endl;
cout << "max_bucket_count:" << m.max_bucket_count() << endl;
cout << "bucket_size:" << m.bucket_size(0) << endl;
std::cout << "load_factor:" << m.load_factor() << std::endl;
std::cout << "max_load_factor:" << m.max_load_factor() << std::endl;
PrintIntDoubleUnOrderedMap(m, "刪除主鍵爲2的元素後的foo1:");
m.clear();
PrintIntDoubleUnOrderedMap(m, "清空後的foo1:");
}
int main()
{
UnOrderedMapExp1();
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
以類作爲key,value
只是用STL提供的基本類型int, char, long等和stringz作爲key,value,STL提供了哈希函數和比較函數。但是用自己定義的類時,需要自己定義哈希函數和比較函數
//hash函數
template <typename T>
class hash
{
public:
size_t operator()(const T& o) const { return 0; }
};
//compare函數
template <typename T>
class equal_to
{
public:
bool operator()(const T& a, const T& b) const { return a == b; }
};
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
下面以一個學號姓名爲例子來實現
#include <unordered_map>
#include <iostream>
#include <string>
using namespace std;
//自己設計類,作爲key和value
//學號
class Number
{
string str;
public:
Number() { }
Number(string s) { str = s; }
const string& get() const
{
return str;
}
};
//姓名
class Name
{
string str;
public:
Name() {}
Name(string s) { str = s; }
const string& get() const
{
return str;
}
};
//哈希函數對象實現
// 必須爲const
class MyHash
{
public:
size_t operator()(const Number& num) const
{
hash<string> sh; //使用STL中hash<string>
return sh(num.get());
}
};
//實現equal_to對象
//必須爲const
class MyEqualTo {
public:
bool operator()(const Number& n1, const Number& n2) const
{
return n1.get() == n2.get();
}
};
int main()
{
unordered_map<Number, Name, MyHash, MyEqualTo> map;
map.emplace(Number("1000"), Name("A"));
map.emplace(Number("1001"), Name("G"));
map.emplace(Number("1002"), Name("E"));
map.emplace(Number("1003"), Name("D"));
unordered_map<Number, Name, MyHash, MyEqualTo>::iterator iter;
Number num("1001");
iter = map.find(num);
if (iter != map.end())
cout << "Number: " << iter->first.get() << "," << "Name: " << iter->second.get() << endl;
else
cout << "Not found!" << endl;
return 0;
}