• 【C++ Primer 第11章】4. 无序容器


    一、介绍

    1. Hashtable和bucket

    由于unordered_map内部采用的hashtable的数据结构存储,所以,每个特定的key会通过一些特定的哈希运算映射到一个特定的位置,我们知道,hashtable是可能存在冲突的(多个key通过计算映射到同一个位置),在同一个位置的元素会按顺序链在后面。所以把这个位置称为一个bucket是十分形象的(像桶子一样,可以装多个元素)。

     所以unordered_map内部其实是由很多哈希桶组成的,每个哈希桶中可能没有元素,也可能有多个元素。

    无序容器管理操作

    • 有序容器通过比较运算符来组织元素
    • 无序容器通过哈希函数和==运算符来组织元素

    这是因为无序容器在存储上组织为一组桶:

    • 哈希函数将元素映射到桶
    • 在桶中搜索某个元素时需要用到==运算符

    如果一个桶中保存了很多元素,那么查找一个特定元素就需要大量比较操作

    无序容器提供了一些管理桶和哈希策略的操作:

    桶接口

    c.bucket_count()
    c.max_bucket_count()
    c.bucket_size(n)
    c.bucket(k)

    桶迭代

    local_iterator
    const_local_iterator
    c.begin(n), c.end(n)
    • c.cbegin(n), c.cend(n)

    哈希策略

    c.load_factor()
    c.max_load_factor()
    c.rehash(n)
    • c.reserve(n)

    2. 构造函数

    unordered_map的构造方式有几种:
     • 构造空的容器
     • 复制构造
     • 范围构造
     • 用数组构造

     1 #include <iostream>
     2 #include <string>
     3 #include <unordered_map>
     4 using namespace std;
     5 
     6 typedef unordered_map<string, string> stringmap;
     7 stringmap merge(stringmap a, stringmap b) 
     8 {
     9     stringmap temp(a); 
    10     temp.insert(b.begin(), b.end()); 
    11     return temp;
    12 }
    13 
    14 int main()
    15 {
    16     stringmap first;                              //
    17     stringmap second({ {"apple", "red"}, {"lemon", "yellow"} });       // 用数组初始
    18     stringmap third({ {"orange", "orange"}, {"strawberry", "red"} });  // 用数组初始
    19     stringmap fourth(second);                    // 复制初始化
    20     stringmap fifth(merge(third, fourth));        // 移动初始化
    21     stringmap sixth(fifth.begin(), fifth.end());  // 范围初始化
    22 
    23     cout << "sixth contains:" << endl;
    24     for (auto& x : sixth) 
    25         cout << x.first << ": " << x.second << endl;
    26     return 0;
    27 }

    运行结果:

     1 #include<string>    
     2 #include<iostream>    
     3 #include<map>    
     4 using namespace std;
     5 
     6 struct person
     7 {
     8     string name;
     9     int age;
    10 
    11     person(string name, int age)
    12     {
    13         this->name = name;
    14         this->age = age;
    15     }
    16 
    17     bool operator < (const person& p) const
    18     {
    19         return this->age < p.age;
    20     }
    21 };
    22 
    23 map<person, int> m;
    24 int main()
    25 {
    26     person p1("Tom1", 20);
    27     person p2("Tom2", 22);
    28     person p3("Tom3", 22);
    29     person p4("Tom4", 23);
    30     person p5("Tom5", 24);
    31     m.insert(make_pair(p3, 100));
    32     m.insert(make_pair(p4, 100));
    33     m.insert(make_pair(p5, 100));
    34     m.insert(make_pair(p1, 100));
    35     m.insert(make_pair(p2, 100));
    36 
    37     for (map<person, int>::iterator iter = m.begin(); iter != m.end(); iter++)
    38     {
    39         cout << iter->first.name << "	" << iter->first.age << endl;
    40     }
    41 
    42     return 0;
    43 }

    运行结果:

    【分析】:因为Tom2和Tom3的age相同,由我们定义的operator<只是比较的age,所以Tom3覆盖了Tom2,结果中没有Tom2。

  • 相关阅读:
    MySQL Unknown table engine 'FEDERATED''
    Meta http-equiv属性与HTTP头的Expires中(Cache-control)详解
    EChart 标题 title 样式,x轴、y轴坐标显示,调整图表位置等
    手机端个人信息模板
    <c:forEach>, <c:forTokens> 标签
    html select 可输入 可编辑
    js写评价的星星
    指数映射
    刚体转动的稳定性
    物理引擎中的刚体转动2
  • 原文地址:https://www.cnblogs.com/sunbines/p/9051314.html
Copyright © 2020-2023  润新知