【C++】unordered 系列关联式容器

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


【C++】unordered 系列关联式容器,C++,哈希算法,c++,数据结构,算法

1. unordered 系列关联式容器

在 C++ 98 中,STL 提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 l o g 2 N log_2 N log2N,即最差情况下需要比较红黑树的高度次,当树中的节点非常多时,查询效率也不理想。最好的查询是:进行很少的比较次数就能将元素找到,因此在 C++ 11 中,STL 又提供了 4 个 unordered 系列的关联式容器,这四个容器与红黑树结构的关联式容器使用方式基本类似,只是其底层结构不同,本文中只对 unordered_map 和 unordered_set 进行介绍。

2. unordered_map

2.1 unordered_map 的文档介绍

unordered_map

  1. unordered_map 是存储 <key, value> 键值对的关联式容器,其允许通过 keys 快速的索引到与其对应的 value。
  2. 在 unordered_map 中,键值通常用于唯一的标识元素,而映射值是一个对象,其内容与此键关联。键和映射值的类型可能不同。
  3. 在内部,unordered_map 没有对 <key, value> 按照任何特定的顺序排序,为了能在常数范围内找到 key 所对应的 value,unordered_map 将相同哈希值的键值对放在相同的桶中。
  4. unordered_map 容器通过 key 访问单个元素要比 map 快,但它通常在遍历元素子集的范围迭代方面效率较低。
  5. unordered_map 实现了直接访问操作符(operator[]),它允许使用 key 作为参数直接访问 value。
  6. 它的迭代器至少是前向迭代器。

2.2 unordered_map 的接口说明

  1. unordered_map 的构造

    函数声明 功能介绍
    unordered_map 构造不同格式的 unordered_map 对象
  2. unordered_map 的容量

    函数声明 功能介绍
    bool empty() const 检测 unordered_map 是否为空
    size_t size() const 获取 unordered_map 的有效元素个数
  3. unordered_map 的迭代器

    函数声明 功能介绍
    begin 返回 unordered_map 第一个元素的迭代器
    end 返回 unordered_map 最后一个元素下一个位置的迭代器
    cbegin 返回 unordered_map 第一个元素的 const 迭代器
    cend 返回 unordered_map 最后一个元素下一个位置的 const 迭代器
  4. unordered_map 的元素访问

    函数声明 功能介绍
    operator[] 返回 key 对应的 value,没有返回一个默认值

    注意:该函数中实际调用哈希桶的插入操作,用参数 key 与 V() 构造一个默认值往底层哈希桶中插入,如果 key 不再哈希桶中,插入成功,返回 V();插入失败,说明 key 已经在哈希桶中,将 key 对应的 value 返回。

  5. unorder_map 的查询

    函数声明 功能介绍
    iterator find(const K& key) 返回 key 在哈希桶中的位置
    size_t count(const K& key) 返回哈希桶中关键码为 key 的键值对的个数

    注意:unordered_map 中 key 是不能重复的,因为 count 函数的返回值最大为 1。

  6. unordered_map 的修改操作

    函数声明 功能介绍
    insert 向容器中插入键值对
    erase 删除容器中的键值对
    void clear() 清空容器中有效元素个数
    void swap(unordered_map&) 交换两个容器中的元素
  7. unordered_map 的桶操作

    函数声明 功能介绍
    size_t bucket_count() const 返回哈希桶中桶的总个数
    size_t bucket_size(size_t n) const 返回 n 号桶中有效元素的总个数
    size_t bucket(const K& key) 返回元素 key 所在的桶号

3. unordered_set

参见 unordered_set 在线文档说明。

4. 在线 OJ

  1. 在长度 2N 的数组中找出重复 N 次的元素

    class Solution
    {
    public:
        int repeatedNTimes(vector<int>& nums)
        {
            int n = nums.size() / 2;
            
            // 用 unordered_map 统计每个元素出现的次数
            unordered_map<int, int> hash;
            for (auto& e : nums)
            {
                ++hash[e];
            }
    
    		// 找出出现次数为 n 的元素个数
            for (auto& e : hash)
            {
                if (e.second == n)
                {
                    return e.first;
                }
            }
    
            return 0;
        }
    };
    
  2. 两个数组的交集

    class Solution
    {
    public:
        vector<int> intersection(vector<int>& nums1, vector<int>& nums2)
        {
        	// 使用 unordered_set 去重
            unordered_set<int> us1;
            for (auto& e : nums1)
            {
                us1.insert(e);
            }
    
            unordered_set<int> us2;
            for (auto& e : nums2)
            {
                us2.insert(e);
            }
    
    		// 遍历 us1,在 us2 中寻找 us1 的每个元素,如果找到,即为交集
            vector<int> ret;
            for (auto& e : us1)
            {
                if (us2.find(e) != us2.end())
                {
                    ret.push_back(e);
                }
            }
    
            return ret;
        }
    };
    
  3. 两个数组的交集 Ⅱ

    class Solution
    {
    public:
        vector<int> intersect(vector<int>& nums1, vector<int>& nums2)
        {
        	// 使用 unordered_map 统计次数
            unordered_map<int, int> um1;
            for (auto& e : nums1)
            {
                ++um1[e];
            }
    
            unordered_map<int, int> um2;
            for (auto& e : nums2)
            {
                ++um2[e];
            }
    
    		// 遍历 um1,在 um2 中查找 um1 的各个元素,并找到该元素出现次数的较小值
            vector<int> ret;
            for (auto& e : um1)
            {
                auto it = um2.find(e.first);
                if (it != um2.end())
                {
                    // 找较小值
                    int less = e.second;
                    if (e.second > (*it).second)
                    {
                        less = (*it).second;
                    }
    
                    // 插入
                    for (int i = 0; i < less; i++)
                    {
                        ret.push_back(e.first);
                    }
                }
            }
    
            return ret;
        }
    };
    
  4. 存在重复元素

    class Solution
    {
    public:
        bool containsDuplicate(vector<int>& nums)
        {
            unordered_map<int, int> um;
            // 我们把 nums 各元素插入到 unordered_map 中
            for (auto& e : nums)
            {
            	// 如果在插入之前发现该元素已经存在于 unordered_map 中,说明该元素是重复的
                if (um.find(e) != um.end())
                {
                    return true;
                }
    
                ++um[e];
            }
    
            return false;
        }
    };
    
  5. 两句话中的不常见单词文章来源地址https://www.toymoban.com/news/detail-847866.html

    class Solution
    {
    public:
        vector<string> uncommonFromSentences(string s1, string s2)
        {
        	// 分析题意,发现要找的单词就是在两个句子中只出现一次的单词
            string str = s1 + " " + s2 + " ";
            unordered_map<string, int> um;
    
            // 分割字符串入哈希表
            int begin = 0, end = 0;
            while (begin < str.size())
            {
                // size_t find (const string& str, size_t pos = 0) const;
                end = str.find(" ", begin);
    
                // string (const string& str, size_t pos, size_t len = npos);
                int npos = end - begin;
                string key(str, begin, npos);
                
                ++um[key];
                begin = end + 1;
            }
    
            // 找到出现次数为 1 的单词
            vector<string> ret;
            for (auto& e : um)
            {
                if (e.second == 1)
                {
                    ret.push_back(e.first);
                }
            }
    
            return ret;
        }
    };
    

END

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

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

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

相关文章

  • 【C++】哈希unordered系列容器的模拟实现

    开散列又叫链地址法(开链法),首先对关键码集合用散列函数计算散列地址,即 key 映射的下标位置,具有相同地址的关键码 (哈希冲突) 归于同一子集合,每一个子集合称为一个桶 (哈希桶),各个桶中的元素通过一个单链表链接起来,各链表的头结点存储在哈希表中;也就

    2024年02月13日
    浏览(27)
  • 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系列封装

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

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

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

    2024年02月07日
    浏览(27)
  • 【C++】unordered系列容器

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

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

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

    2024年02月06日
    浏览(25)
  • C++数据结构与算法——哈希表

    C++第二阶段——数据结构和算法,之前学过一点点数据结构,当时是基于Python来学习的,现在基于C++查漏补缺,尤其是树的部分。这一部分计划一个月,主要利用代码随想录来学习,刷题使用力扣网站,不定时更新,欢迎关注! 给定两个字符串 s 和 t ,编写一个函数来判断

    2024年02月19日
    浏览(46)
  • C++ unordered_map哈希表

    leetcode: 49. 字母异位词分组 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。 示例 1: 输入: strs = [“eat”, “tea”, “tan”, “ate”, “

    2023年04月25日
    浏览(34)
  • 【C++】哈希表封装实现 unordered_map 和 unordered_set

    在 C++98 中,STL 提供了底层为红黑树结构的一系列关联式容器,在查询时效率可达到 O(logN),即最差情况下只需要比较红黑树的高度次;但是当树中的节点非常多时,其查询效率也不够极致。 最好的查询是,不进行比较或只进行常数次比较就能够将元素找到,因此在 C++11 中,

    2023年04月16日
    浏览(37)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包