【STL】unodered_map

来源:互联网 发布:单片机与plc区别 编辑:程序博客网 时间:2024/06/06 07:03

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;    }};//哈希函数对象实现// 必须为constclass MyHash {public:    size_t operator()(const Number& num) const    {        hash<string> sh;        //使用STL中hash<string>        return sh(num.get());    }};//实现equal_to对象//必须为constclass 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;}
原创粉丝点击