• c++ unordered_set


    unordered_set

    可直译为“无序 set 容器”,即 unordered_set 容器和 set 容器很像,唯一的区别就在于 set 容器会自行对存储的数据进行排序,而 unordered_set 容器不会。
    本质是使用hash散列的方式存储数据,是一种使用hash值作为key的容器,所以当有频繁的搜索、插入和移除拥有常数时间。
    unordered_set存储原理是声明一个有n个桶的数据结构,计算加入到unordered_set的新的值hash,然后计算hash%n后的值x,将新的值加入到桶x中。当桶x中已经有了元素,就直接链接在后边。当数据结构中的元素满足一定数量时需要扩充桶的数量,并重新构建桶结构。

    特点

    1. unordered_set是一种容器,它以不特定的顺序存储唯一的元素,并允许根据元素的值快速检索单个元素。
    2. 在unordered_set中,元素的值同时是唯一标识它的键。键是不可变的,只可增删,不可修改。
    3. 在内部,unordered_set中的元素没有按照任何特定的顺序排序,而是根据它们的散列值组织成桶(一个线性链表代表一个桶),从而允许通过它们的值直接快速访问单个元素(平均时间复杂度为常数)。
    4. unordered_set容器比set容器更快地通过它们的键访问单个元素,尽管它们在元素子集的范围迭代中通常效率较低。
    5. 容器中的迭代器只能是正向迭代器。

    基本使用

    初始化

    调用 unordered_set 模板类的默认构造函数,可以创建空的 unordered_set 容器

    std::unordered_set<std::string> uset;
    
    • 1

    创建 unordered_set 容器的同时,可以完成初始化操作

    std::unordered_set<std::string> c{ "aaa", "bbb", "ccc" }
    
    • 1

    调用 unordered_set 模板中提供的复制(拷贝)构造函数,将现有 unordered_set 容器中存储的元素全部用于为新建 unordered_set 容器初始化

    std::unordered_set<std::string> uset2(uset);
    
    • 1

    以右值引用的方式,利用临时 unordered_set 容器中存储的所有元素,给新建容器初始化

    //返回临时 unordered_set 容器的函数
    std::unordered_set <std::string> retuset() {
        std::unordered_set<std::string> tempuset{ "aaa", "bbb", "ccc" };
        return tempuset;
    }
    //调用移动构造函数,创建 uset 容器
    std::unordered_set<std::string> uset(retuset());
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    使用 unordered_set 类模板提供的迭代器,在现有 unordered_set 容器中选择部分区域内的元素,为新建 unordered_set 容器初始化

    //传入 2 个迭代器,
    std::unordered_set<std::string> uset2(++uset.begin(),uset.end());
    
    • 1
    • 2

    添加元素

    c.insert("dddd"):向容器添加元素”dddd"
    
    a.insert({ "aaa","bbbb","cccc" }):向容器添加元素"aaa","bbbb","cccc"
    
    a.insert(b.begin(), b.end()):b是一个存储着和a相同类型元素的向量,可将b中所有元素添加到a中
    
    • 1
    • 2
    • 3
    • 4
    • 5

    查找元素

    a.find("eeee"):查找元素"eeee",返回结果为a.end()则表明没有找到,否则返回所对应元素
    
    a.count("eeee"):查找元素"eeee"在a中有几个(由于unordered_set中没有相同的元素,所以结果通常为01
    • 1
    • 2
    • 3

    查找桶接口

    a.bucket_count():返回数据结构中桶的数量
    
    a.bucket_size(i):返回桶i中的大小
    
    a.bucket(“eeee"):返回元素"eeee"在哪个桶里
    
    • 1
    • 2
    • 3
    • 4
    • 5

    观察器

    a.hash_function()("aaa"):返回"aaa"所对应的hash值;
    
    a.key_eq()("aaa","aaaa") :当元素相同时返回true,否则返回false
    • 1
    • 2
    • 3

    清除元素

    a.clear():清除a中所有元素;
    
    a.erase("aaa"):清除元素"aaa"
    • 1
    • 2
    • 3

    统计函数

    a.size():返回a中总的元素个数;
    
    a.max_size():返回a中最大容纳元素;
    
    a.empty():判断a中是否为空
    
    • 1
    • 2
    • 3
    • 4
    • 5

    方法列表

    成员方法功能
    begin()返回指向容器中第一个元素的正向迭代器
    end();返回指向容器中最后一个元素之后位置的正向迭代器
    cbegin()和 begin() 功能相同,只不过其返回的是 const 类型的正向迭代器
    cend()和 end() 功能相同,只不过其返回的是 const 类型的正向迭代器
    empty()若容器为空,则返回 true;否则 false
    size()返回当前容器中存有元素的个数
    max_size()返回容器所能容纳元素的最大个数,不同的操作系统,其返回值亦不相同
    find(key)查找以值为 key 的元素,如果找到,则返回一个指向该元素的正向迭代器;反之,则返回一个指向容器中最后一个元素之后位置的迭代器(如果 end() 方法返回的迭代器)
    count(key)在容器中查找值为 key 的元素的个数
    equal_range(key)返回一个 pair 对象,其包含 2 个迭代器,用于表明当前容器中值为 key 的元素所在的范围
    emplace()向容器中添加新元素,效率比 insert() 方法高
    emplace_hint()向容器中添加新元素,效率比 insert() 方法高
    insert()向容器中添加新元素
    erase()删除指定元素
    clear()清空容器,即删除容器中存储的所有元素
    swap()交换 2 个 unordered_set 容器存储的元素,前提是必须保证这 2 个容器的类型完全相等
    bucket_count()返回当前容器底层存储元素时,使用桶(一个线性链表代表一个桶)的数量
    max_bucket_count()返回当前系统中,unordered_set 容器底层最多可以使用多少桶
    bucket_size(n)返回第 n 个桶中存储元素的数量
    bucket(key)返回值为 key 的元素所在桶的编号
    load_factor()返回 unordered_set 容器中当前的负载因子。负载因子,指的是的当前容器中存储元素的数量(size())和使用桶数(bucket_count())的比值,即 load_factor() = size() / bucket_count()
    max_load_factor()返回或者设置当前 unordered_set 容器的负载因子
    rehash(n)将当前容器底层使用桶的数量设置为 n
    reserve()将存储桶的数量(也就是 bucket_count() 方法的返回值)设置为至少容纳 count 个元(不超过最大负载因子)所需的数量,并重新整理容器
    hash_function()返回当前容器使用的哈希函数对象
  • 相关阅读:
    【Java校招面试】实战面经(十)
    java计算机毕业设计家政服务网站源程序+mysql+系统+lw文档+远程调试
    用辗转相除法求两个整数的最大公约数
    [管理与领导-100]:管理者到底是什么?调度器?路由器?交换机?监控器?
    java镜子之反射篇
    每日汇评:黄金将测试1935美元的200日移动均线
    1059 C语言竞赛
    Spring Cloud微服务:Loadbalancer 实战
    Rust中级教程:指针生态(引用、原始指针、智能指针)and内存操作(Stack、Heap)
    七天.NET 8操作SQLite入门到实战 - 第六天后端班级管理相关接口完善和Swagger自定义配置
  • 原文地址:https://blog.csdn.net/weixin_44347020/article/details/133128148