【C++】unordered系列容器

这篇具有很好参考价值的文章主要介绍了【C++】unordered系列容器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【C++】unordered系列容器

1、unordered容器介绍

unordered容器是C++标准库中提供的一组无序关联式容器,用于存储和管理无序的数据集合。这些容器的特点是快速的查找、插入和删除操作,其内部实现通常基于哈希表(hash table)。

C++标准库提供了四种unordered容器:

  1. unordered_set:无序唯一元素集合,存储一组唯一的元素,不允许重复。
  2. unordered_multiset:无序元素集合,存储一组元素,允许重复。
  3. unordered_map:无序键值对集合,存储一组唯一的键值对,每个键只能出现一次。
  4. unordered_multimap:无序键值对集合,存储一组键值对,允许键的重复。

这些容器的特点如下:

  1. 无序性:unordered容器中的元素没有特定的顺序,与插入的顺序无关。元素的存储位置是根据其哈希值来确定的,而不是根据比较操作符。这使得无序容器在查找操作上具有常数时间复杂度,而有序容器通常需要对元素进行排序和比较。

  2. 哈希表实现:unordered容器内部通常使用哈希表实现。哈希表是一种将元素的键映射到存储位置的数据结构,通过使用哈希函数将键转换为存储桶的索引。这样可以在平均情况下实现常数时间的插入、查找和删除操作。

  3. 高效的插入和删除:由于无序容器使用哈希表,插入和删除操作的时间复杂度通常是常数时间。这使得无序容器特别适用于需要频繁插入和删除元素的场景。

  4. 自定义键类型:无序容器支持使用自定义类型作为键。为了支持自定义类型,需要提供自定义的哈希函数和相等比较函数。

使用unordered容器的步骤如下:

  1. 包含头文件:在使用unordered容器之前,需要包含 <unordered_set>, <unordered_map> 头文件,并使用适当的命名空间(例如 std)。

  2. 创建容器对象:使用容器的类型名称和模板参数,声明一个容器对象。

  3. 插入和访问元素:使用容器的成员函数来插入和访问元素。

  4. 查找和删除元素:使用成员函数进行元素的查找和删除操作。

无序容器还提供了许多其他的成员函数和操作,如 size() 返回容器中的元素数量,clear() 清空容器等。具体的使用方法和注意事项可以在C++标准库的文档中找到。

2、unordered_map

2.1 介绍

  1. unordered_map是一种关联式容器,用于存储键值对(key-value pair)。通过键(key),可以快速地索引到与之关联的值(value)。

  2. 在unordered_map中,键用于唯一地标识元素,而映射值则是与键相关联的对象。键和映射值的类型可以不同。

  3. unordered_map内部使用哈希表(hash table)实现,相同哈希值的键值对被放置在相同的桶中。它并不对键值对按任何特定顺序进行排序,而是根据哈希值来组织元素。

  4. 由于unordered_map的内部实现是基于哈希表,通过键进行单个元素的访问速度比有序容器(如map)要快。然而,当需要遍历元素子集时,unordered_map的效率可能较低,因为元素的顺序是无序的。

  5. unordered_map实现了直接访问操作符(operator[]),允许使用键作为参数直接访问对应的值。例如:value = myMap[key];

  6. unordered_map的迭代器至少是前向迭代器,可以用于遍历容器中的元素。可以使用迭代器来访问键值对、进行插入、删除等操作。

2.2 接口说明以及使用

2.2.1 构造

unordered_map提供了多种构造函数,可以根据不同的需求进行初始化。以下是一些常用的构造函数及其使用示例:

  1. 默认构造函数:

    std::unordered_map<Key, T> myMap;
    

    示例:

    std::unordered_map<std::string, int> myMap; // 创建一个空的unordered_map
    
  2. 初始化列表构造函数:

    std::unordered_map<Key, T> myMap = {{key1, value1}, {key2, value2}, ...};
    

    示例:

    std::unordered_map<std::string, int> myMap = {{"apple", 5}, {"banana", 3}, {"orange", 2}}; // 创建并初始化一个unordered_map
    
  3. 范围构造函数:

    template <typename InputIt>
    std::unordered_map<Key, T> myMap(InputIt first, InputIt last);
    

    示例:

    std::vector<std::pair<std::string, int>> data = {{"apple", 5}, {"banana", 3}, {"orange", 2}};
    std::unordered_map<std::string, int> myMap(data.begin(), data.end()); // 通过范围构造函数创建unordered_map
    
  4. 拷贝构造函数:

    std::unordered_map<Key, T> myMap(otherMap);
    

    示例:

    std::unordered_map<std::string, int> myMap(otherMap); // 通过拷贝构造函数创建unordered_map
    
  5. 移动构造函数:

    std::unordered_map<Key, T> myMap(std::move(otherMap));
    

    示例:

    std::unordered_map<std::string, int> myMap(std::move(otherMap)); // 通过移动构造函数创建unordered_map
    

在上述示例中,“Key” 表示unordered_map中的键类型,“T” 表示unordered_map中的值类型。

2.2.2 容量函数

在unordered_map中,您可以使用以下两个成员函数来查询容器的状态和大小:

  1. empty():此函数用于检查unordered_map是否为空。如果容器为空,返回true;否则,返回false。

    bool empty() const;
    

    示例:

    std::unordered_map<std::string, int> myMap;
    if (myMap.empty()) {
        std::cout << "myMap is empty." << std::endl;
    }
    
  2. size():此函数返回unordered_map中存储的键值对数量。

    size_t size() const;
    

    示例:

    std::unordered_map<std::string, int> myMap = {{"apple", 5}, {"banana", 3}, {"orange", 2}};
    size_t mapSize = myMap.size();
    std::cout << "myMap size: " << mapSize << std::endl;
    

这些函数可以了解unordered_map的当前状态和大小。可以根据需要使用它们来编写相关的逻辑或进行容器的控制流程。

上述示例中的std::unordered_map<std::string, int>可以根据实际的键和值类型进行调整。

2.2.3 迭代器

在unordered_map中,可以使用以下四个成员函数来获取迭代器以遍历容器中的元素:

  1. begin():返回指向unordered_map中第一个元素的迭代器。

    iterator begin();
    

    示例:

    std::unordered_map<std::string, int> myMap = {{"apple", 5}, {"banana", 3}, {"orange", 2}};
    auto it = myMap.begin(); // 获取指向第一个元素的迭代器
    
  2. end():返回指向unordered_map中最后一个元素之后位置的迭代器。

    iterator end();
    

    示例:

    std::unordered_map<std::string, int> myMap = {{"apple", 5}, {"banana", 3}, {"orange", 2}};
    auto it = myMap.end(); // 获取指向最后一个元素之后位置的迭代器
    
  3. cbegin():返回指向unordered_map中第一个元素的const迭代器。

    const_iterator cbegin() const;
    

    示例:

    const std::unordered_map<std::string, int> myMap = {{"apple", 5}, {"banana", 3}, {"orange", 2}};
    auto it = myMap.cbegin(); // 获取指向第一个元素的const迭代器
    
  4. cend():返回指向unordered_map中最后一个元素之后位置的const迭代器。

    const_iterator cend() const;
    

    示例:

    const std::unordered_map<std::string, int> myMap = {{"apple", 5}, {"banana", 3}, {"orange", 2}};
    auto it = myMap.cend(); // 获取指向最后一个元素之后位置的const迭代器
    

使用这些函数可以获取迭代器,然后可以使用迭代器来遍历unordered_map中的键值对,进行插入、删除或其他操作。

上述示例中的std::unordered_map<std::string, int>可以根据实际的键和值类型进行调整。

2.2.4 修改操作

在unordered_map中,可以使用以下几个成员函数来插入、删除、清空和交换容器中的元素:

  1. insert():插入一个键值对或一组键值对到unordered_map中。

    std::pair<iterator, bool> insert(const value_type& value);
    iterator insert(const_iterator hint, const value_type& value);
    template <typename InputIt>
    void insert(InputIt first, InputIt last);
    

    示例:

    std::unordered_map<std::string, int> myMap;
    
    // 插入单个键值对
    myMap.insert(std::make_pair("apple", 5));
    
    // 插入一组键值对
    std::vector<std::pair<std::string, int>> data = {{"banana", 3}, {"orange", 2}};
    myMap.insert(data.begin(), data.end());
    
  2. erase():从unordered_map中删除一个或一组键值对。

    iterator erase(iterator pos);
    size_type erase(const key_type& key);
    iterator erase(const_iterator first, const_iterator last);
    

    示例:

    std::unordered_map<std::string, int> myMap = {{"apple", 5}, {"banana", 3}, {"orange", 2}};
    
    // 删除单个键值对
    myMap.erase("apple");
    
    // 删除一组键值对
    auto it = myMap.find("banana");
    if (it != myMap.end()) {
        myMap.erase(it, myMap.end());
    }
    
  3. clear():清空unordered_map中的所有键值对,使其成为空容器。

    void clear();
    

    示例:

    std::unordered_map<std::string, int> myMap = {{"apple", 5}, {"banana", 3}, {"orange", 2}};
    myMap.clear(); // 清空unordered_map
    
  4. swap():交换两个unordered_map的内容,使其互相交换。

    void swap(unordered_map& other);
    

    示例:

    std::unordered_map<std::string, int> myMap1 = {{"apple", 5}};
    std::unordered_map<std::string, int> myMap2 = {{"banana", 3}, {"orange", 2}};
    
    myMap1.swap(myMap2); // 交换两个unordered_map的内容
    

这些函数可用于对unordered_map进行插入、删除、清空和交换操作。请根据实际需求选择适当的函数进行操作。

上述示例中的std::unordered_map<std::string, int>可以根据实际的键和值类型进行调整。

2.2.5 查找操作

在unordered_map中,可以使用以下两个成员函数来查找键和计算特定键的数量:

  1. find():查找给定键在unordered_map中的位置,并返回一个指向该位置的迭代器。

    iterator find(const key_type& key);
    const_iterator find(const key_type& key) const;
    

    示例:

    std::unordered_map<std::string, int> myMap = {{"apple", 5}, {"banana", 3}, {"orange", 2}};
    
    auto it = myMap.find("apple");
    if (it != myMap.end()) {
        // 键 "apple" 存在于unordered_map中
        std::cout << "Value: " << it->second << std::endl;
    }
    
  2. count():计算特定键在unordered_map中的数量,并返回该数量。

    size_type count(const key_type& key) const;
    

    示例:

    std::unordered_map<std::string, int> myMap = {{"apple", 5}, {"banana", 3}, {"orange", 2}};
    
    if (myMap.count("apple") > 0) {
        // 键 "apple" 存在于unordered_map中
        std::cout << "Key 'apple' found." << std::endl;
    }
    

请注意,find() 函数返回一个迭代器,指向unordered_map中键为给定键的元素。如果元素不存在,则返回unordered_map的end()迭代器。

count() 函数返回给定键在unordered_map中的数量。由于unordered_map的键是唯一的,返回值只能是0或1。

上述示例中的std::unordered_map<std::string, int>可以根据实际的键和值类型进行调整。

2.2.6 桶操作

在关联式容器(包括unordered_map)中,桶(bucket)是容器内部的一个存储区域,用于存放元素。桶操作是指对这些存储桶进行访问和操作的功能。

unordered_map内部使用哈希表(hash table)来组织和存储元素。哈希表根据键的哈希值将元素映射到特定的存储桶中。每个存储桶可以包含零个或多个元素。桶操作允许直接访问和操作这些存储桶,以便更好地了解和控制unordered_map的内部结构和性能。

以下是一些常见的桶操作:

  1. bucket_count():返回unordered_map中的存储桶的数量。

    size_type bucket_count() const;
    
  2. bucket_size():返回特定存储桶中的元素数量。

    size_type bucket_size(size_type n) const;
    
  3. bucket():返回给定键的元素所在的存储桶的索引。

    size_type bucket(const key_type& key) const;
    
  4. begin(bucket_index):返回指向特定存储桶中第一个元素的迭代器。

    local_iterator begin(size_type n);
    
  5. end(bucket_index):返回指向特定存储桶中最后一个元素之后位置的迭代器。

    local_iterator end(size_type n);
    

通过这些桶操作可以了解unordered_map中存储桶的数量、每个存储桶中的元素数量,以及特定键所在的存储桶索引。还可以使用迭代器来遍历特定存储桶中的元素。

这些桶操作是unordered_map的特定成员函数,用于提供对存储桶的访问和操作功能。

3、unordered_set

具体接口函数可以自行查找

这里说明它与unordered_map间的异同点:

unordered_map和unordered_set是C++标准库中提供的两种容器,它们有以下相同点和不同点:

相同点:

  1. 底层实现:unordered_map和unordered_set都是基于哈希表(hash table)实现的,利用哈希函数将元素映射到存储桶中,以实现高效的插入、查找和删除操作。

  2. 查找效率:无论是unordered_map还是unordered_set,都具有快速的查找效率。由于哈希表的特性,平均情况下,它们的查找操作的时间复杂度为常数。

  3. 迭代器:unordered_map和unordered_set都提供了迭代器(iterator),可以用于遍历容器中的元素。

  4. 自定义键类型:两者都支持使用自定义类型作为键。需要提供自定义的哈希函数和相等比较函数来支持自定义键类型。

不同点:

  1. 存储方式:unordered_map存储键值对(key-value pair),而unordered_set只存储唯一的值(value)。unordered_map使用键来唯一标识和访问每个元素,而unordered_set仅依靠值来唯一标识每个元素。

  2. 元素类型:unordered_map中的元素是键值对,其中键和值的类型可以不同。而unordered_set中的元素只包含值,类型由模板参数指定。

  3. 存储结构:由于unordered_map存储键值对,因此它的存储结构相对于unordered_set要复杂一些。unordered_map中的每个存储桶都存储了一个键值对,而unordered_set中的每个存储桶只存储一个值。

  4. 插入操作:在unordered_map中,插入一个新的键值对时,需要同时提供键和值。而在unordered_set中,插入一个新值只需要提供该值即可。

总体上,unordered_map适用于需要存储键值对的情况,可以通过键快速访问对应的值;而unordered_set适用于只需存储独特值的情况,可以快速判断某个值是否存在。文章来源地址https://www.toymoban.com/news/detail-564619.html

到了这里,关于【C++】unordered系列容器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++ | 数据结构】从哈希的概念 到封装C++STL中的unordered系列容器

    引入: 顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。顺序查找时间复杂度为O(N),平衡树中为树的高度,即O( l o g 2 N log_2 N l o g 2 ​ N ),搜索的效率取决于搜索过程中元素的比较次数。 尽管平

    2024年01月22日
    浏览(33)
  • 哈希——unordered系列关联式容器

      目录 unordered系列关联式容器 概念 unordered_map 无序+去重 operator[] unordered_set 无序+去重 OJ练习题 重复n次的元素 两个数组的交集  两个数的交集二  底层结构 概念  哈希冲突 闭散列 结点的定义 扩容 字符串取模 插入 查找 删除 闭散列完整代码  开散列 结点定义 释放桶(析构

    2023年04月17日
    浏览(21)
  • C++:关联式容器:unordered_map

    目录 1.unordered_ map特性 2. 常用接口的使用 1.insert          2.find 3.erase ​4.operator[ ]  3.迭代器的有效性 1. unordered_map是存储key, value键值对的关联式容器,其允许通过keys快速的索引到与 其对应的value。 2. 在unordered_map中,键值通常用于惟一地标识元素,而映射值是一个对象,

    2024年02月09日
    浏览(29)
  • 【C++关联式容器】unordered_map

    目录 unordered_map 1. pair类型 2. 关联式容器额外的类型别名 3. 哈希桶 4. 无序容器对类型的要求 5. Member functions 5.1 constructor、destructor、operator= 5.1.1 constructor 5.1.2 destructor 5.1.3 operator=  5.2 Capacity ​5.2.1 empty 5.2.2 size 5.2.3 max_size 5.3 Iterators 5.4 Element access 5.4.1 operator[] 5.4.2 at 5

    2024年02月22日
    浏览(33)
  • 【C++】哈希表封装unordered系列

      文章目录 前言 一、哈希表的封装 总结 在看本篇文章前大家尽量拿出上一篇文章的代码跟着一步步实现,否则很容易引出大量模板错误而无法解决。 一、哈希表的封装 首先我们要解决映射的问题,我们目前的代码只能映射整形,那么如何支撑浮点数等的映射呢?只需要多

    2024年02月07日
    浏览(28)
  • 【C++】哈希和unordered系列封装

    顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。顺序查找时间复杂度为O(N),平衡树中为树的高度,即O( l o g 2 N log_2 N l o g 2 ​ N ),搜索的效率取决于搜索过程中元素的比较次数。 理想的搜索方

    2024年02月02日
    浏览(21)
  • STL容器——unordered_set的用法

    unordered_set 容器,可直译为 无序 set 容器 。即 unordered_set 容器和 set 容器很像,唯一的区别就在于 set 容器会自行对存储的数据进行排序,而 unordered_set 容器不会。 下面是 set 、 multiset 和 unordered_set 之间的差别。 注意这三种集合的底层实现,他决定了算法的时间复杂度。特别

    2024年02月09日
    浏览(34)
  • 哈希表封装unordered系列

    本篇文章的大框架部分详解见红黑树封装map和set那篇博客,大框架我就不细讲了,主要说明一下小细节,源码采用哈希桶并且哈希桶的方式能够更好的解决冲突问题,因此再次以哈希桶为基准进行改良进而封unodered_set 和unordered_map。 还是像map和set部分一样,节点模板参数改为

    2024年02月06日
    浏览(25)
  • 【C++】unordered_map,unordered_set模拟实现

    喜欢的点赞,收藏,关注一下把! 上一篇文章我们把unordered_map和unordered_set底层哈希桶的知识也都说清楚了,今天就根据哈希桶模拟实现出unordered_map和unordered_set。 这里如果看过以前文章【C++】map和set的模拟实现,应该会觉得简单。 因为unordered_map和unordered_set底层都是哈希桶

    2024年01月21日
    浏览(34)
  • 【C++入门到精通】哈希 (STL) _ unordered_map _ unordered_set [ C++入门 ]

    欢迎各位大佬们的关顾,本文将介绍unordered系列容器以及其中的两个重要成员: unordered_map 和 unordered_set 。unordered_map是一种无序的关联容器,它使用哈希表来存储键值对,并提供高效的插入、查找和删除操作。在本文中,我们将首先介绍unordered_map的基本概念和特点,然后详

    2024年02月08日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包