乔拓云网站建设新网站秒收录技术

web/2025/10/5 22:03:39/文章来源:
乔拓云网站建设,新网站秒收录技术,广东省造价工程信息网,各省网站备案条件unordered_map与unordered_set的实现 文章目录 unordered_map与unordered_set的实现前言一、问题一HashTable.h 二、问题二问题三1.封装时如何取出key2.不同类型key如何建立对应关系 三、问题四问题五问题四问题五 四、实现代码MyUnorderedSet.hMyUnorderedMap.hHash…unordered_map与unordered_set的实现 文章目录 unordered_map与unordered_set的实现前言一、问题一HashTable.h 二、问题二问题三1.封装时如何取出key2.不同类型key如何建立对应关系 三、问题四问题五问题四问题五 四、实现代码MyUnorderedSet.hMyUnorderedMap.hHashTable.h 前言 在C11中新增了两个很好用的容器分别是unordered_map与unordered_set和map和set有不同之处 map与set的底层实现是平衡树——红黑树并且采取中序遍历时默认有序 而本文的unordered_map与unordered_set底层实现是哈希思想拉链法并且他的存储方式不支持排序所以是unordered 两者的查找效率综合比较会发现unordered_map与unordered_set的效率综合会更高所以在C11中支持了unordered_map与unordered_set 本文中是用哈希桶的拉链法来封装unordered_map与unordered_set 这里的封装与红黑树封装map和set的封装相似但此处会更难 具体通过解决问题来实现 HashTable的迭代器实现封装时HashTable如何取出map的key和set的key取出key后如何针对不同类型key建立映射关系如何解决Set中key不能被修改Map中key不能被修改value能被修改的问题Insert插入返回值问题以及Map[]的重载实现 关于哈希思想及其具体实现细节看我的上篇文章数据结构之哈希表 一、问题一 这里就一步步先实现iterator再实现const_iterator版本了而是直接放出能适配iterator与const_iterator的版本本质上就是用类模板泛型编程需要什么就调用什么是什么类型就返回什么类型的迭代器 这里尤为注意的一点是这里的迭代器是单向迭代器只支持而由于底层是哈希表的拉链法实现的是数组与链表结合的方式 在实现运算符重载时本质上就是在逐个遍历哈希桶而当前桶走完的时候需要进入下一个桶那么如何判断当前桶的位置以及如何找到下一个桶就需要把这个数组或者整个哈希表传过来这里我们做的是把整个哈希表传过来 注意其实将数组传过来会更简单些传哈希表会有一些问题 我们将哈希表传过来是可能要访问哈希表内的私有变量来获得下一个桶而直接在_HTIterator这个类内使用哈希表内的私有变量是不可取的所以需要在哈希表内声明友元此处还涉及编译问题由于编译器是从上往下编译代码我们将迭代器写在哈希表代码的上面而迭代器中有哈希表这里编译器并不认识哈希表因为哈希表的定义还未出现所以还需要哈希表对应的类的声明 templateclass K, class T, class Ref, class Ptr, class KeyOfT, class Hashfriend struct _HTIterator;templateclass K, class T, class KeyOfT, class Hashclass HashTable;至于class KeyOfT 与 class Hash这两个类模板的作用则在下文中解答 HashTable.h namespace hash_bucket {templateclass Tstruct HashNode{HashNode(const T data):_data(data),_next(nullptr){}T _data;HashNode* _next;};templateclass K, class T, class KeyOfT, class Hashclass HashTable;templateclass K, class T, class Ref, class Ptr, class KeyOfT, class Hashstruct _HTIterator{typedef HashNodeT Node;typedef _HTIteratorK, T, Ref, Ptr, KeyOfT, Hash Self;typedef _HTIteratorK, T, T, T*, KeyOfT, Hash iterator;_HTIterator(Node* node, HashTableK, T, KeyOfT, Hash* pht):_node(node),_pht(pht){}_HTIterator(Node* node, const HashTableK, T, KeyOfT, Hash* pht):_node(node), _pht(pht){}_HTIterator(const iterator x):_node(x._node), _pht(x._pht){}Ref operator*(){return _node-_data;}Ptr operator-(){return _node-_data;}Self operator(){Hash hf;KeyOfT kot;size_t hashi hf(kot(_node-_data)) % _pht-_t.size();if (_node-_next ! nullptr){_node _node-_next;}else{hashi;while (hashi _pht-_t.size()){if (_pht-_t[hashi]){_node _pht-_t[hashi];break;}hashi;}}if (hashi _pht-_t.size()){_node nullptr;}return *this;}bool operator(const Self it){return _node it._node;}bool operator!(const Self it){return _node ! it._node;}const HashTableK, T, KeyOfT, Hash* _pht;Node* _node;};templateclass K, class T, class KeyOfT, class Hashclass HashTable{typedef HashNodeT Node;templateclass K, class T, class Ref, class Ptr, class KeyOfT, class Hashfriend struct _HTIterator;public:HashTable(size_t n 10){_t.resize(n);}typedef _HTIteratorK, T, T, T*, KeyOfT, Hash iterator;typedef _HTIteratorK, T, const T, const T*, KeyOfT, Hash const_iterator;iterator begin(){size_t hashi 0;while (hashi _t.size()){if (_t[hashi]){break;}hashi;}if (hashi _t.size()){return iterator(nullptr, this);}return iterator(_t[hashi], this);}iterator end(){return iterator(nullptr, this);}const_iterator begin()const{size_t hashi 0;while (hashi _t.size()){if (_t[hashi]){break;}hashi;}if (hashi _t.size()){return iterator(nullptr, this);}return iterator(_t[hashi], this);}const_iterator end()const{return iterator(nullptr, this);}pairiterator,bool Insert(const T data){KeyOfT kot;Hash hf;iterator ret Find(kot(data));if (ret ! end()){return make_pair(ret, false);}//扩容if (_n / _t.size() 1){size_t newsize _t.size() * 2;HashTable newtable(newsize);for (int i 0; i _n; i){Node* cur _t[i];while (cur){Node* next cur-_next;size_t hashi hf(kot(cur-_data)) % newsize;cur-_next newtable._t[hashi];newtable._t[hashi] cur;cur next;}_t[i] nullptr;}swap(_t, newtable._t);}size_t hashi hf(kot(data)) % _t.size();Node* newnode new Node(data);newnode-_next _t[hashi];_t[hashi] newnode;_n;return make_pair(iterator(newnode, this), true);}iterator Find(const K key){Hash hf;KeyOfT kot;size_t hashi hf(key) % _t.size();Node* cur _t[hashi];while (cur){if (kot(cur-_data) key){return iterator(cur, this);}cur cur-_next;}return iterator(nullptr, this);}bool Erase(const K key){Hash hf;KeyOfT kot;size_t hashi hf(key) % _t.size();Node* cur _t[hashi];Node* prev nullptr;if (kot(cur-_data) key){_t[hashi] cur-_next;delete cur;return true;}while (cur){if (kot(cur-_data) key){prev-_next cur-_next;delete cur;_n--;return true;}prev cur;cur cur-_next;}return false;}private:vectorHashNodeT* _t;size_t _n 0;}; }二、问题二问题三 1.封装时如何取出key 首先解释一下问题我们的目的是将unordered_map与unordered_set用哈希表封装实现map中存的是pairset中存的是key而如何用一份哈希表适配两种结构呢 在封装的时候解决这个问题在unordered_map与unordered_set中写一个内部类这个类之中实现了一个仿函数用来返回key并且将其传给哈希表内 templateclass K, class V, class Hash HashFuncKclass unordered_map{public:struct KeyOfT{const K operator()(const pairK, V kv){return kv.first;}};private:hash_bucket::HashTableK, pairconst K, V, KeyOfT, Hash _ht;}; templateclass K, class Hash HashFuncKclass unordered_set{public:struct KeyOfT{const K operator()(const K key){return key;}};private:hash_bucket::HashTableK, K, KeyOfT, Hash _ht;};2.不同类型key如何建立对应关系 本文的拉链法中使用的哈希函数是除留余数法如果key是int类型的话那正好可以直接用key除但如果key是string或者自定义类型那么就不能够直接除了则需要将其转换成int类型另外一个模板参数Hash则是将其转换方式传给哈希表 如果是内置类型的floatdouble之类的我们可以直接强转成size_t返回 如果是string类型由于string比较常用我们可以为string搞个特化默认支持string 上面两个都是默认支持的用默认缺省值就行不需要手动传Hash 而如果是自定义类型则需要使用者通过接口手动传Hash因为默认的缺省值用不了 templateclass K struct HashFunc {size_t operator()(const K key){return (size_t)key;} };template struct HashFuncstring {size_t operator()(const string key){size_t hash 0;for (auto e : key){hash * 13;hash e;}return hash;} };三、问题四问题五 问题四与问题五与set与map用红黑树封装的问题相同 问题四 set的iterator和const_iterator都是红黑树的const_iterator复用而来 map中的iterator是红黑树的iterator复用而来const_iterator是红黑树的const_iterator复用而来 既然set中的迭代器都是const_iterator所以key自然不能被修改 typedef typename hash_bucket::HashTableK, K, KeyOfT, Hash::const_iterator iterator;typedef typename hash_bucket::HashTableK, K, KeyOfT, Hash::const_iterator const_iterator;map解决key不能被修改value能被修改的原理也很简单就是在实例化的时候声明第二个模板参数——在map中也就是pairpair的first是const类型 private:hash_bucket::HashTableK, pairconst K, V, KeyOfT, Hash _ht;问题五 unordered_map与unordered_set与map和set的红黑树封装相同insert的返回值都是一个键值对 first是一个迭代器second是一个bool类型 基于此性质引出了map的计数功能可以通过insert返回的迭代器查看是否有key值如果不存在则插入将value值赋值为1如果key已经存在则通过insert返回的迭代器将value以此实现计数功能所以map实现了operator[]用来计数 V operator[](const K key){return _ht.Insert(make_pair(key, V())).first-second;}四、实现代码 MyUnorderedSet.h #include HashTable.hnamespace Tlzns {templateclass K, class Hash HashFuncKclass unordered_set{public:struct KeyOfT{const K operator()(const K key){return key;}};typedef typename hash_bucket::HashTableK, K, KeyOfT, Hash::const_iterator iterator;typedef typename hash_bucket::HashTableK, K, KeyOfT, Hash::const_iterator const_iterator;iterator begin()const{return _ht.begin();}iterator end()const{return _ht.end();}pairiterator, bool Insert(const K key){auto ret _ht.Insert(key);return pairiterator, bool(iterator(ret.first._node, ret.first._pht), ret.second);}bool Erase(const K key){return _ht.Erase(key);}iterator Find(const K key){return _ht.Find(key);}private:hash_bucket::HashTableK, K, KeyOfT, Hash _ht;};void test_set(){unordered_setint us;us.Insert(5);us.Insert(15);us.Insert(52);us.Insert(3);unordered_setint::iterator it us.begin();while (it ! us.end()){//*it 5;cout *it ;it;}cout endl;for (auto e : us){cout e ;}cout endl;} } MyUnorderedMap.h #include HashTable.hnamespace Tlzns {templateclass K, class V, class Hash HashFuncKclass unordered_map{public:struct KeyOfT{const K operator()(const pairK, V kv){return kv.first;}};typedef typename hash_bucket::HashTableK, pairconst K, V, KeyOfT, Hash::iterator iterator;typedef typename hash_bucket::HashTableK, pairconst K, V, KeyOfT, Hash::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();}pairiterator, bool Insert(const pairK, V kv){return _ht.Insert(kv);}bool Erase(const K key){return _ht.Erase(key);}iterator Find(const K key){return _ht.Find(key);}V operator[](const K key){return _ht.Insert(make_pair(key, V())).first-second;}private:hash_bucket::HashTableK, pairconst K, V, KeyOfT, Hash _ht;};void test_map(){unordered_mapstring, string dict;dict.Insert(make_pair(sort, ));dict.Insert(make_pair(string, ));dict.Insert(make_pair(insert, ));unordered_mapstring, string::const_iterator it dict.begin();for (auto kv : dict){//kv.first x;kv.second x;cout kv.first : kv.second endl;}cout endl;string arr[] { 香蕉, 甜瓜,苹果, 西瓜, 苹果, 西瓜, 苹果, 苹果, 西瓜, 苹果, 香蕉, 苹果, 香蕉 };unordered_mapstring, int count_map;for (auto e : arr){count_map[e];}for (auto kv : count_map){cout kv.first : kv.second endl;}cout endl;} }HashTable.h #include iostream #include vectorusing namespace std;templateclass K struct HashFunc {size_t operator()(const K key){return (size_t)key;} };template struct HashFuncstring {size_t operator()(const string key){size_t hash 0;for (auto e : key){hash * 13;hash e;}return hash;} };namespace hash_bucket {templateclass Tstruct HashNode{HashNode(const T data):_data(data),_next(nullptr){}T _data;HashNode* _next;};templateclass K, class T, class KeyOfT, class Hashclass HashTable;templateclass K, class T, class Ref, class Ptr, class KeyOfT, class Hashstruct _HTIterator{typedef HashNodeT Node;typedef _HTIteratorK, T, Ref, Ptr, KeyOfT, Hash Self;typedef _HTIteratorK, T, T, T*, KeyOfT, Hash iterator;_HTIterator(Node* node, HashTableK, T, KeyOfT, Hash* pht):_node(node),_pht(pht){}_HTIterator(Node* node, const HashTableK, T, KeyOfT, Hash* pht):_node(node), _pht(pht){}_HTIterator(const iterator x):_node(x._node), _pht(x._pht){}Ref operator*(){return _node-_data;}Ptr operator-(){return _node-_data;}Self operator(){Hash hf;KeyOfT kot;size_t hashi hf(kot(_node-_data)) % _pht-_t.size();if (_node-_next ! nullptr){_node _node-_next;}else{hashi;while (hashi _pht-_t.size()){if (_pht-_t[hashi]){_node _pht-_t[hashi];break;}hashi;}}if (hashi _pht-_t.size()){_node nullptr;}return *this;}bool operator(const Self it){return _node it._node;}bool operator!(const Self it){return _node ! it._node;}const HashTableK, T, KeyOfT, Hash* _pht;Node* _node;};templateclass K, class T, class KeyOfT, class Hashclass HashTable{typedef HashNodeT Node;templateclass K, class T, class Ref, class Ptr, class KeyOfT, class Hashfriend struct _HTIterator;public:HashTable(size_t n 10){_t.resize(n);}typedef _HTIteratorK, T, T, T*, KeyOfT, Hash iterator;typedef _HTIteratorK, T, const T, const T*, KeyOfT, Hash const_iterator;iterator begin(){size_t hashi 0;while (hashi _t.size()){if (_t[hashi]){break;}hashi;}if (hashi _t.size()){return iterator(nullptr, this);}return iterator(_t[hashi], this);}iterator end(){return iterator(nullptr, this);}const_iterator begin()const{size_t hashi 0;while (hashi _t.size()){if (_t[hashi]){break;}hashi;}if (hashi _t.size()){return iterator(nullptr, this);}return iterator(_t[hashi], this);}const_iterator end()const{return iterator(nullptr, this);}pairiterator,bool Insert(const T data){KeyOfT kot;Hash hf;iterator ret Find(kot(data));if (ret ! end()){return make_pair(ret, false);}//扩容if (_n / _t.size() 1){size_t newsize _t.size() * 2;HashTable newtable(newsize);for (int i 0; i _n; i){Node* cur _t[i];while (cur){Node* next cur-_next;size_t hashi hf(kot(cur-_data)) % newsize;cur-_next newtable._t[hashi];newtable._t[hashi] cur;cur next;}_t[i] nullptr;}swap(_t, newtable._t);}size_t hashi hf(kot(data)) % _t.size();Node* newnode new Node(data);newnode-_next _t[hashi];_t[hashi] newnode;_n;return make_pair(iterator(newnode, this), true);}iterator Find(const K key){Hash hf;KeyOfT kot;size_t hashi hf(key) % _t.size();Node* cur _t[hashi];while (cur){if (kot(cur-_data) key){return iterator(cur, this);}cur cur-_next;}return iterator(nullptr, this);}bool Erase(const K key){Hash hf;KeyOfT kot;size_t hashi hf(key) % _t.size();Node* cur _t[hashi];Node* prev nullptr;if (kot(cur-_data) key){_t[hashi] cur-_next;delete cur;return true;}while (cur){if (kot(cur-_data) key){prev-_next cur-_next;delete cur;_n--;return true;}prev cur;cur cur-_next;}return false;}private:vectorHashNodeT* _t;size_t _n 0;}; }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/87574.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浙江耀华建设集团网站企业网站建设制作设计哪家最专业

StarRocks 于 4 月底正式发布了 3.0 版本,该里程碑版本带来了大家期盼已久的新特性--存算分离。此新功能一推出,立即受到社区热情追捧,用户纷纷开始在自己的业务中评估和测试存算分离效果。从芒果TV、聚水潭、网易邮箱、浪潮、天道金科等数十…

西安手机网站建设动力无限长沙短视频公司

项目右侧的Maven依赖Dependencies突然消失,项目中的注解都出现报错,出现这种情况应该是因为IDEA版本早于maven版本,重新检查项目中的Maven路径,选择File->Settings->搜索Maven,检查Maven home directory&#xf…

网站支付怎么做中国软件100强企业

自上周怒辞职以后,就開始苦逼的各种面试生涯,生活全然靠私活来接济,时有时没有,真难。还能快乐的玩耍吗。最多一天面试了5家,哎感觉都是不急招人,各种等待通知。好不easy等来一家。还克扣了薪资&#xff0c…

适合公司建设的网站网页棋牌搭建

1前言大家好,我是若川。最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12 参与,已进行三个月了,大家一起交流学习,共同进步。想学源码,极力推荐之前我写的《学习源码整体架构系列》 包含jQuery、un…

国外注册域名的网站晚上偷偷奖励自己的软件

在经济飞速发展的今天,企业面临着客户需求多样化、质量和交期要求提高以及激烈的市场竞争等挑战。在这样的背景下,许多企业开始考虑采用数字化仓储WMS系统来解决这些问题。 数字化仓储WMS系统通过打造高效、规范的仓库管理体系,实现了对产品…

ps如何做ppt模板下载网站网站建设yuanmus

前几天在书写TypeScript代码时,出现了声明变量报错的情况,具体情况如下: let arr: number; arr 10; console.log(arr);报错如下: 解决方案: 在配置文件tsconfig.json中,配置如下代码: { &q…

哪个网站可以做视频外链wordpress扁平化中文主题

死锁(Deadlock)是指两个或多个进程在执行过程中因争夺资源而造成的一种互相等待的现象 死锁通常发生在多任务系统中,其中进程通过竞争有限的资源来完成任务 死锁通常涉及互斥、持有和等待三个条件。 死锁的原因 互斥条件(Mutual…

雷州网站wordpress 文章结尾处

性能优化指南 1.骨架屏 业务可以在数据加载完成之前用骨架屏幕来占位,提升体验。 2.包大小优化 减小包中静态资源,例如图片文件,可将图片进行压缩降低文件体积。无用文件、函数、样式剔除。除了部分用于容错的图片必须放在代码包&#xf…

开通微网站龙岩微信小程序定制

目录 一、前言1、项目介绍2、图片测试效果展示 二、项目环境配置1、pytorch安装(gpu版本和cpu版本的安装)2、pycocotools的安装3、其他包的安装 三、yolov8/yolov7/yolov5CRNN-中文车牌识别、车牌关键点定位、车牌检测算法1、yolov8算法介绍2、CRNN算法介绍3、算法流…

网站整体排名大幅下降网站建设和网页设计的关系

亲爱的创作者们,大家好!今天我们来聊聊视频创作中至关重要的一点——氛围感。一个好的视频,不仅要有视觉冲击力,还要能够触动观众的情感。那我们应该去哪里寻找这些充满氛围感且高级的视频素材呢?别急,我这…

花都高端网站建设wordpress 动态解析

文章目录1. 多线程1.1 QTimer1.2 QThread界面卡住例子分离UI和工作线程1.3 事件处理2. 网页交互显示本地 html显示 html 代码调用 JavaScriptJavaScript 调用 PyQt代码learn from 《PyQt5 快速开发与实战》 https://doc.qt.io/qtforpython/index.html https://www.riverbankcom…

门户网站的布局贵阳市城乡建设学校网站

之前一直困扰自己的一个问题就是表单内radio、select等的对齐问题,一直以来,都是给提示添加label,然后跟radio等一起浮动,然后再设置margin解决的,但是这样又得另外解决IE6下的双边距问题,搞得自己相当恼。…

o2o网站模版网站开发完成情况说明

题干: JYY有两棵树A和B:树A有N个点,编号为1到N;树B有N1个点,编号为1到N1。JYY知道树B恰好是由树A加上一个叶 节点,然后将节点的编号打乱后得到的。他想知道,这个多余的叶子到底是树B中的哪一个…

后台风格网站短视频推广代理

golangvue微服务电商系统 文章目录 golangvue微服务电商系统一、项目前置准备二、项目简介三、代码GItee地址 golang、vue redis、mysql、gin、nacos、es、kibana、jwt 一、项目前置准备 环境的搭建 官方go开发工程师参考地址:https://blog.csdn.net/qq23001186/cat…

汕头市企业网站建设服务机构漳州建设银行网站

文章目录 “Q*”可能是什么?何为AI意识的产生?AI应该如何与人类对齐? 上周,OpenAI人事风波暂停的尾声中,有个“可能威胁人类”的、代号为“Q*”的神秘项目被抛掷出来。 传言中,Sam Altman被解雇前&#xff…

网站做留言板关于服装的网站规划与设计

近日,由中国网络空间安全协会主办,中国网络空间安全协会网络空间安全法律与公共政策专业委员会、北京邮电大学互联网治理与法律研究中心、公安部第三研究所网络安全法律研究中心、西安交通大学信息安全法律研究中心承办的《网络安全法(草案二…

做视频的网站带模板苏醒主题wordpress

一、引言 时间复杂度是衡量算法运行效率的一项重要指标,它描述了随着输入规模的增加,算法的执行时间如何增长。在算法设计与分析中,我们经常面临着优化时间复杂度的任务,以便提高程序的性能。本博客将深入探讨时间复杂度的优化法…

如何自己创建购物网站国家建筑信息管理平台

数学实验A 本仓库收集了2024年我在学习《数学实验A》课程期间完成的作业。课程使用的教材为《MATLAB数学实验》第三版,作者为胡良剑和孙晓君教授。 这个资源库的建立初衷是为了帮助南京邮电大学的同学们在学习过程中有一个参考的依据,减少一些无端浪费…

初创业公司做网站网站代码免费下载

一. pager-taglib-2.0简介预览. pager-taglib-2.0支持多种风格的分页,打开其源码,可以看到,处理标签的类为: PagerTag,有兴趣的同学可以研究下源码。 Simple: Text Icon: JSPTags.com : AllTheW…