当前位置: 首页 > backend >正文

C++效率掌握之STL库:unordered_map unordered_set底层剖析

文章目录

  • 1.unordered_map、unordered_set的基本结构
  • 2.普通迭代器
  • 3.const迭代器
  • 4.insert返回值 operator[]
  • 希望读者们多多三连支持
  • 小编会继续更新
  • 你们的鼓励就是我前进的动力!

看了前面的底层封装后,其实封装的过程及方法都大差不差,unordered_map && unordered_set 也是如此,所以本篇就简单提及一些细节,具体最详细的一些部分可以去看前面的文章

传送门:C++效率掌握之STL库:list底层剖析及迭代器万字详解

传送门:C++效率掌握之STL库:map && set底层剖析及迭代器万字详解

1.unordered_map、unordered_set的基本结构

🚩unordered_set:

template<class K, class V>
class unordered_set
{struct SetKeyOfT{const K& operator()(const K& key){return key;}};
public:typedef typename hash_bucket::HashTable<K, K, SetKeyOfT>::const_iterator iterator;typedef typename hash_bucket::HashTable<K, K, SetKeyOfT>::const_iterator const_iterator;const_iterator begin() const{return _ht.begin();}const_iterator end() const{return _ht.end();}pair<const_iterator, bool> insert(const K& key){pair<typename hash_bucket::HashTable<K, K, SetKeyOfT>::iterator, bool> ret = _ht.Insert(key);return pair<const_iterator, bool>(ret.first, ret.second);}
private:hash_bucket::HashTable<K, K, SetKeyOfT> _ht;
};

🚩unordered_map:

template<class K, class V>
class unordered_map
{struct MapKeyOfT{const K& operator()(const pair<const K, V>& kv){return kv.first;}};
public:typedef typename hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT>::iterator iterator;typedef typename hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT>::const_iterator const_iterator;iterator begin(){return _ht.begin();}iterator end(){return _ht.end();}const_iterator begin() const{return _ht.begin();}const_iterator end() const{return _ht.end();}pair<iterator, bool> insert(const pair<K, V>& kv){return _ht.Insert(kv);}V& operator[](const K& key){pair<iterator, bool> ret = _ht.Insert(make_pair(key, V()));return ret.first->second;}
private:hash_bucket::HashTable<K, pair<const K, V>, MapKeyOfT> _ht;
};

unordered_set 虽然事 k-k 类型,unordered_mapk-v 类型,但是实际上这两个类共用一个哈希表,准确来说是共用同一个模板类型,unordered_set<K,K>unordered_map<K,pair<K,V>>

2.普通迭代器

template<class K, class T, class Ptr, class Ref, class KeyOfT, class HashFunc>
struct HTIterator
{typedef HashNode<T> Node;typedef HTIterator<K, T, Ptr, Ref, KeyOfT, HashFunc> Self;typedef HTIterator<K, T, T*, T&, KeyOfT, HashFunc> Iterator;Node* _node;const HashTable<K, T, KeyOfT, HashFunc>* _pht;/*HTIterator(Node* node, HashTable<K, T, KeyOfT, HashFunc>* pht):_node(node),_pht(pht){}*/HTIterator(Node* node, const HashTable<K, T, KeyOfT, HashFunc>* pht):_node(node), _pht(pht){}// 普通迭代器时,他是拷贝构造// const迭代器时,他是构造HTIterator(const Iterator& it):_node(it._node), _pht(it._pht){}Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}Self& operator++(){if (_node->_next){// 当前桶还没完_node = _node->_next;}else{KeyOfT kot;HashFunc hf;size_t hashi = hf(kot(_node->_data)) % _pht->_table.size();// 从下一个位置查找查找下一个不为空的桶++hashi;while (hashi < _pht->_table.size()){if (_pht->_table[hashi]){_node = _pht->_table[hashi];return *this;}else{++hashi;}}_node = nullptr;}return *this;}bool operator!=(const Self& s){return _node != s._node;}bool operator==(const Self& s){return _node == s._node;}
};

typedef HTIterator<K, T, T*, T&, KeyOfT, HashFunc> Iterator 和构造函数是为 Insert 操作准备的,因为涉及到普通迭代器创建 const 迭代器

🔥值得注意的是: 有人说不是可以通过权限转化吗?但是权限转化是只有涉及引用和指针的类型时才会生效,而这里是模板参数之间的转化

3.const迭代器

unordered_set 本身无论是 const 迭代器还是普通迭代器都会被 typedefconst_iterator

对于 unordered_map 来说,key 是不允许改变的,value 是可以改变的,但是如果像 set 那样写的话 keyvalue 都不能修改了,所以直接在 pairkeyconst ,控制 value 即可

4.insert返回值 operator[]

🚩unordered_set:

pair<const_iterator, bool> insert(const K& key)
{//return _ht.Insert(key);pair<typename hash_bucket::HashTable<K, K, SetKeyOfT>::iterator, bool> ret = _ht.Insert(key);return pair<const_iterator, bool>(ret.first, ret.second);
}

🚩unordered_map:

pair<iterator, bool> insert(const pair<K, V>& kv)
{return _ht.Insert(kv);
}V& operator[](const K& key)
{pair<iterator, bool> ret = _ht.Insert(make_pair(key, V()));return ret.first->second;
}

这里的转化尤为复杂,一定要看之前文章的详细解析

希望读者们多多三连支持

小编会继续更新

你们的鼓励就是我前进的动力!

请添加图片描述

http://www.xdnf.cn/news/8206.html

相关文章:

  • JavaScript【8】异步请求与本地存储
  • 巢票赛演协议逆向分析
  • 建设工程窝工、停工损失案件庭审发问提纲
  • [Dify] 在Dify中优雅处理本地部署LLM的Token超限问题
  • TransMorph:用于无监督医学图像配准的变压器
  • 网络编程中的 Protobuf 和 JsonCpp 全面解析
  • 视频监控管理平台EasyCVR结合AI分析技术构建高空抛物智能监控系统,筑牢社区安全防护网
  • Dify-4:API 后端架构
  • C#学习11——集合
  • 电机试验平台:实现高效精密测试的关键工具
  • 蓝桥杯 10. 安全序列
  • 今日行情明日机会——20250522
  • Linux 部署 RocketMQ
  • 基于江协标准库所出现的定时器5678以及串口45等无法使用的问题解析
  • 写实交互数字人在AI招聘中的应用方案
  • UE5 Va Res发送请求、处理请求、json使用
  • React 如何封装一个可复用的 Ant Design 组件
  • 学习日记-day13-5.22
  • Dockers Compose常用指令介绍
  • matlab实现无线通信组
  • PG Craft靶机复现 宏macro攻击
  • 第33节:迁移学习与模型微调策略
  • 微服务的应用案例
  • HashMap的基础用法(java)
  • [Harmony]WebView基本用法
  • WebGL基本概念
  • C++:RAII的不能顾名思义?
  • docker多阶段构建镜像
  • gd32e230c8t6 驱动ws2812
  • 几种直流电流采样方法