【STL】unodered_map

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 的成員類型。 

被映射的值的類型。 
在類模板內部,使用其別名爲 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章