STL源码分析之hash_map配接器

c++中hash_table以及std::map应用案例 代码重点是hash_table,附加std::map与其做对比,实现的是一条sql语句:select c_nationkey, c_mktsegment, count(*), max(c_acctbal) from aaa_customer_1g group by c_nationkey, c_mktsegment order by c_nationkey, c_mktsegment 立即下载

前言

hash_map是以hashtable为底层的配接器, 他与map的功能基本一样, 只是map是有序的将键值插入, 而hash_map则是无序的插入键值, 本节也简单对它做一个分析.

hash_map分析

类型定义

#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Key, class T, class HashFcn = hash<Key>,
          class EqualKey = equal_to<Key>,
          class Alloc = alloc>
#else
template <class Key, class T, class HashFcn, class EqualKey, 
          class Alloc = alloc>
#endif
class hash_map
{
private:
    // 定义hashtable
  typedef hashtable<pair<const Key, T>, Key, HashFcn,
                    select1st<pair<const Key, T> >, EqualKey, Alloc> ht;
  ht rep;

public:
    // 类型定义
  typedef typename ht::key_type key_type;
  typedef T data_type;
  typedef T mapped_type;
  typedef typename ht::value_type value_type;
  typedef typename ht::hasher hasher;
  typedef typename ht::key_equal key_equal;

  typedef typename ht::size_type size_type;
  typedef typename ht::difference_type difference_type;
  typedef typename ht::pointer pointer;
  typedef typename ht::const_pointer const_pointer;
  typedef typename ht::reference reference;
  typedef typename ht::const_reference const_reference;

  typedef typename ht::iterator iterator;
  typedef typename ht::const_iterator const_iterator;
	// 返回值是仿函数
  hasher hash_funct() const { return rep.hash_funct(); }
  key_equal key_eq() const { return rep.key_eq(); }
    ...
};

构造函数

class hash_map
{
	...
public:
    // 构造函数
  hash_map() : rep(100, hasher(), key_equal()) {}	// 默认构造函数
  explicit hash_map(size_type n) : rep(n, hasher(), key_equal()) {}
  hash_map(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
  hash_map(size_type n, const hasher& hf, const key_equal& eql)
    : rep(n, hf, eql) {}
	// 接受迭代器
  template <class InputIterator>
  hash_map(InputIterator f, InputIterator l)
    : rep(100, hasher(), key_equal()) { rep.insert_unique(f, l); }
  template <class InputIterator>
  hash_map(InputIterator f, InputIterator l, size_type n)
    : rep(n, hasher(), key_equal()) { rep.insert_unique(f, l); }
  template <class InputIterator>
  hash_map(InputIterator f, InputIterator l, size_type n,
           const hasher& hf)
    : rep(n, hf, key_equal()) { rep.insert_unique(f, l); }
  template <class InputIterator>
  hash_map(InputIterator f, InputIterator l, size_type n,
           const hasher& hf, const key_equal& eql)
    : rep(n, hf, eql) { rep.insert_unique(f, l); }
    ...
};
class hash_map
{
	...
public:
  size_type size() const { return rep.size(); }	// map中的元素个数
  size_type max_size() const { return rep.max_size(); }
  bool empty() const { return rep.empty(); }
  void swap(hash_map& hs) { rep.swap(hs.rep); }

    // 获取迭代器
  iterator begin() { return rep.begin(); }
  iterator end() { return rep.end(); }
  const_iterator begin() const { return rep.begin(); }
  const_iterator end() const { return rep.end(); }
  iterator find(const key_type& key) { return rep.find(key); }
  const_iterator find(const key_type& key) const { return rep.find(key); }
  size_type count(const key_type& key) const { return rep.count(key); }	// 获取一个元素出现的个数, map中count=0可以表示不存在
    ...
};

重载

class hash_map
{
	...
public:
  friend bool operator== __STL_NULL_TMPL_ARGS (const hash_map&, const hash_map&);
    
  T& operator[](const key_type& key) {
    return rep.find_or_insert(value_type(key, T())).second;
  }
    ...
};
template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
inline bool operator==(const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm1,
                       const hash_map<Key, T, HashFcn, EqualKey, Alloc>& hm2)
{
  return hm1.rep == hm2.rep;
}

insert等函数

insert_unique不重复的插入元素

class hash_map
{
	...
public:
  // 不重复的插入元素
  pair<iterator, bool> insert(const value_type& obj)
    { return rep.insert_unique(obj); }
#ifdef __STL_MEMBER_TEMPLATES
    // 接受迭代器
  template <class InputIterator>
  void insert(InputIterator f, InputIterator l) { rep.insert_unique(f,l); }
#else
  void insert(const value_type* f, const value_type* l) {
    rep.insert_unique(f,l);
  }
  void insert(const_iterator f, const_iterator l) { rep.insert_unique(f, l); }
#endif /*__STL_MEMBER_TEMPLATES */
  pair<iterator, bool> insert_noresize(const value_type& obj)
    { return rep.insert_unique_noresize(obj); }    
  
  pair<iterator, iterator> equal_range(const key_type& key)
    { return rep.equal_range(key); }
  pair<const_iterator, const_iterator> equal_range(const key_type& key) const
    { return rep.equal_range(key); }

    // 删除元素
  size_type erase(const key_type& key) {return rep.erase(key); }
  void erase(iterator it) { rep.erase(it); }
  void erase(iterator f, iterator l) { rep.erase(f, l); }
  void clear() { rep.clear(); }

public:
  void resize(size_type hint) { rep.resize(hint); }
  size_type bucket_count() const { return rep.bucket_count(); }
  size_type max_bucket_count() const { return rep.max_bucket_count(); }
  size_type elems_in_bucket(size_type n) const
    { return rep.elems_in_bucket(n); }
};

总结

本节对hash_map做了简单的分析, 基本上的分析都和前面的set, map等一样, 都是调用接口并进行封装就成了一个新的结构. hash_map也是不能重复的插入相同的键, 并且不能修改键. 与map区别在于它插入和删除的时间复杂度是O(1), 并且插入是无序的.

hashmap的C++实现 hashmap的C++实现,对于学习C++方面的很有用 立即下载

相关推荐

《UE4游戏开发》之 《查cook资源失败,问题记录》

当项目打包时,cook出错,但是从原始引擎提供的信息中,没有提示具体的那个资源出错,要查到出错资源,还是非常麻烦。 下面就材质cook出错,增加一些日志,方便查找问题做简单记录 材质cook的一个阶段,是收集MaterialShaderMap,如果在这个阶段收集的信息出错,将会在FShaderMapContent::GetOutdatedTypes函数中,因为Shaders指针指向的内存有问题而出错,通过断点发现,FShaderMapContent这个类对象指针为null,而这个类对象的来源于AllMat.

qq_21919621的博客 2580

详细解说STL hash_map系列

0 为什么需要hash_map 用过map吧?map提供一个很常用的功能,那就是提供key-value的存储和查找功能。例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改: 岳不群-华山派掌门人,人称君子剑张三丰-武当掌门人,太极拳创始人东方不败-第一高手,葵花宝典...这些信息如果保存下来并不复杂,但是找起来比较麻烦。例如我要找"张三丰"的信息,最傻的方法就是取得所有的记录,然后

fisher_jiang的专栏 3211

机器学习的学习准则(期望风险最小化、经验风险最小化、结构风险最小化)

要评价模型f(x, θ)的好坏,可通过期望风险R(θ)来衡量:求期望损失R(θ)不仅需要知道损失函数还需要知道真实分布,损失函数可以通过一定的准则计算得到,但是样本空间的真实分布是未知的。所以不能直接求R(θ)。期望风险R(θ)无法计算,给定一个训练集D =,我们可以计算经验风险,经验风险就是在训练集上的平均损失:为了解决过拟合问题,引入了参数正则化来限制模型的能力。使其不要过度的最小化经验风险。这种准则就是结构风险最小化准则

... 2225

std::hash_map的使用

std::hash_map的使用(基于VC2010)   一. std::hash_map的定义 // std::hash_map的定义 template<class _Kty, // Key class _Ty, // Value class _Tr = hash_compare >, // 哈希比较器(里面也调用了普通的比较器) class _Alloc = alloca

cay22的专栏 4995

VBA学习笔记6:将多个工作表中满足条件的数据汇总到同一个工作表

VBA学习笔记6:将多个工作表中满足条件的数据汇总到同一个工作表

weixin_45355881的博客 4708

kali虚拟机-----破解wifi密码(WiFi渗透)

文章目录一、将无线网卡挂载到 虚拟机上二、查看是否挂载成功三、查看网卡是否支持监听模式四、检查文件监听影响并杀死影响五、开启无线监听模式六、开始监听七、开始抓包(新建一个命令窗口)八、对已连接的终端进行攻击,使它掉线重连,以此来获取数据包。(新建一个命令窗口)九、开始解密 一、将无线网卡挂载到 虚拟机上 可能出现的问题:在可移动设备处无法连接无线网卡; 解决:在虚拟机设置中将usb控制器设置成如图所示。 注意要先关闭虚拟机在设置。 二、查看是否挂载成功 使用ifconfig命令查看 三、查看网卡是

weixin_46471800的博客 1万+

hashmap详解

标准std中中的map,是使用平衡二叉树实现的,查找和添加的复杂度都为O(log(n)),  标准std中中的hashmap,是使用hashtable实现的,查找和添加的复杂度都为O(1),  gnu c++提供了hash_map,是一个hash map的实现,查找和添加复杂 度均为O(1)。  #include #ifdef __GNUC__ #include #else #

tianmo2010的专栏 2523

告别手动!用Python+CATIA V5/V6自动生成三视图和标题栏(附完整代码)

本文详细介绍了如何利用Python和CATIA V5/V6实现工程图自动生成,包括三视图布局和标题栏填写。通过COM接口调用和智能算法,系统能自适应不同尺寸模型,大幅提升设计效率。附完整代码和部署方案,帮助团队实现从手动到自动化的转变。

weixin_42699679的博客 353

std::hash和unordered_map用法,C++自定义哈希表

std::hash是实现了仿函数的类模板,根据传入不同数据类型T,获得其哈希值。 返回值类型:size_t。 对于C/C++内置数据类型,已经实现了其哈希函数,自定义数据类型需要定义其哈希值的求值方式。C++中的哈希表是通过unordered_map实现的,它是一种关联容器,可以将键值对存储在其中。它的特点是快速查找,插入和删除,时间复杂度为O(1)。

weixin_40355471的博客 3946

鸿蒙读书笔记1:《鸿蒙操作系统设计原理与架构》

GUI、 语 音 控 制 方 式 的 VUI(Voice User Interface, 语 音 用 户 界。电话、多媒体、DFX、MSDP(Multimodal Sensor Data Platform,多。面)、手势/姿态控制的CVUI(Computer Vision User Interface,计算。KAL(Kernel Abstract Layer,内核抽象层)通过屏蔽多内核差异,JavaScript、C、C++等多语言的用户程序开发框架,以及UI框架、

jackyrongvip的专栏 2449

ESP32水墨屏日历实战:低功耗自动更新与HTTPS数据解析

本文详细介绍了ESP32水墨屏日历项目的开发实践,重点讲解了低功耗自动更新与HTTPS数据解析的实现方法。通过ESP32的自动休眠功能和水墨屏的零功耗特性,结合HTTPS请求安全获取网络数据,实现了高效节能的桌面日历应用。项目代码开源,适合物联网开发者参考。

xx56789的博客 777

C++进阶——STL源码之unordered_set与unordered_multiset

STL源码之unordered_set与unordered_multiset std::set 是关联容器,含有 Key 类型对象的已排序集。用比较函数 Compare 进行排序。搜索、移除和插入拥有对数复杂度。 set 通常以红黑树实现,红黑树具有自动排序的功能,因此set内部所有的数据,在任何时候,都是有序的。 std::unordered_set 是含有 Key 类型唯一对象集合的关联容器,依赖于哈希表。搜索、插入和移除拥有平均常数时间复杂度。在内部,元素并不以任何特别顺序排序,而是组织进桶中,元

qq_25065595的博客 949

【用unity实现100个游戏之15】开发一个类保卫萝卜的Unity2D塔防游戏1(附项目源码)

当今,塔防游戏已经成为游戏市场上备受欢迎的一类游戏类型。《保卫萝卜》作为其中的经典之作,深受玩家喜爱。本项目旨在基于《保卫萝卜》的玩法和特点,开发一个Unity2D塔防游戏,让玩家可以在游戏中体验到精彩的策略对抗与刺激的关卡挑战。本项目将通过Unity引擎进行开发,利用2D游戏开发相关技术,包括但不限于精灵动画、碰撞检测、UI界面设计等。我们将实现萝卜作为关键角色的防守任务,并设计各种怪物和防御塔,使得游戏具有多样的战术策略和游戏乐趣。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 4924

STL源码分析目录

SIG STL源码分析 前言 本专栏主要以STL源码剖析分析路线来分析SIGSTL3.0源码. 整个模块准备对学习STL源码剖析之后做一个系统的总结, 这些都是我个人的理解, 如果分析有什么问题欢迎各位大佬们指出. 也很感谢作者以及网络中各个大佬的总结, 让我也能更容易更深刻的理解到STL强大和方便, 也让我对template感受深刻. 以下是我自己对STL版块进行分析. 总共分为六个版块 : 空...

啦啦啦 3637

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

STL源码分析

一、STL简介 STL提供六大组件,彼此可以组合套用: 容器 容器就是各种数据结构,我就不多说,看看下面这张图回忆一下就好了,从实现角度看,STL容器是一种class template。 算法 各种常见算法,如sort,search,copy,erase等,我觉得其中比较值得学习的就是sort,next_permutation,partition,merge sort,从实现角度

qq_19272431的博客 2328

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

stl源码剖析总体

优化程序性能:根据容器的特性选择合适的容器,避免不必要的性能损耗。扩展STL功能:理解仿函数和配接器的原理,实现自定义的策略和功能。提升编程能力:学习泛型编程和模板元编程技术,提高代码的复用性和可维护性。建议阅读STL的经典书籍,如《STL源码剖析》,结合实际的代码实践,加深对STL的理解和应用。

sina123的博客 534

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

STL源码分析之hash_multimap配接器

前言 上节分析了hash_map知道它是不允许存在相同的键存在, 本节的hash_multimap就可以允许存在多个相同的键, 以hashtable为接口, 这里我就只分析与hash_map的不同点吧, 毕竟很多都是一样的了, 没有必要重复的分析相同的代码. insert 最大的区别就在这里, hash_multimap 是以insert_equal为接口, 所以支持插入重复的键. #ifndef...

啦啦啦 555

stl 基于哈希的map c++_笔记目录 (对象模型、STL容器、C++技巧)

(本专栏仅是个人笔记本,有胡言乱语和错漏之处 )C++对象模型蓝色海上漂:C++ GCC 对象模型 从汇编代码分析虚函数、动态绑定原理 (Part 1) —— 结合汇编代码和fdump-class-hierarchy分析了GCC中多重继承下的对象在内存中的对象模型,以及虚函数表、动态绑定的底层实现。蓝色海上漂:C++ GCC 对象模型 dynamic_cast实现 (Part 2) —— ...

weixin_39957265的博客 113

STL源码分析(未完待续7/04)

文章目录1.STL六大组件介绍1)简介2)文件分类3)头文件包含关系a) 空间配置器(allocator)b) 容器(container)c) 算法(algorithm)d) 迭代器(iterator)2.源码剖析1)迭代器a) 迭代器失效2)容器a) vector底层源码讲解(1)图解(2)几点注解(3)vector容器函数讲解a) 构造函数和析构函数b)属性获取:begin\end\size\capacity\emptyc ) push 和 pop 操作d ) erase 删除元素e ) insert

谢白羽 470

STL源码剖析

STL源码剖析——空间配置器 STL源码剖析——Traits编程技术 STL源码剖析——迭代器 STL源码剖析——全局函数 STL源码剖析——序列容器之vector STL源码剖析——list容器的排序算法sort() STL源码剖析——序列容器之list STL源码剖析——序列容器之deque STL源码剖析——容器配接器之stack STL源码剖析——容器配接器之queue STL源码剖析——...

zzxiaozhao的博客 477

STL源码剖析 笔记

STL 6大组件: 1、容器:各种数据结构,如vector set

boyhailong的专栏 935

STL源码剖析章节介绍

内容:介绍STL的历史演进(从1979年概念提出到1998年纳入C++标准库)、六大组件(容器、算法、迭代器、仿函数、适配器、空间配置器)的协作机制,以及SGI、GNU、MSVC等主流实现版本的差异。关键知识点:STL的设计哲学(高复用性、低耦合性)、前闭后开区间表示法、临时对象优化等。

u010632343的博客 592

面试题总结(三)、《STL源码剖析》相关面试题总结

声明:本文主要探讨与STL实现相关的面试题,主要参考侯捷的《STL源码剖析》,每一个知识点讨论力求简洁,便于记忆,但讨论深度有限,如要深入研究可点击参考链接,希望对正在找工作的同学有点帮助。 一、STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看下面这张图回忆一下就好了,从实现角度看,STL容器是一种class template。 算法各种常...

weixin_34050427的博客 546

《STL源码剖析》相关面试题总结

原文地址:https://www.cnblogs.com/raichen/p/5817158.html《STL源码剖析》相关面试题总结一、STL简介STL提供六大组件,彼此可以组合套用:容器容器就是各种数据结构,我就不多说,看看下面这张图回忆一下就好了,从实现角度看,STL容器是一种class template。算法各种常见算法,如sort,search,copy,erase等,我觉得其中比较值得...

caogenwangbaoqiang的博客 493

STL源码分析读书笔记--第5章--关联式容器

1.关联式容器的概念 上一篇文章讲序列式容器,序列式容器的概念与关联式容器相对,不提供按序索引。它分为set和map两大类,这两大类各自有各自的衍生体multiset和multimap,的底层机制都是用红黑树实现,红黑树是一种基本平衡的二叉搜索树,红黑树的原理wiki上讲得很清楚,书中只是把算法实现在了底层而已,在SGI STL中RB-tree是作为底层数据结构供其他容器配接用,因此关联容...

weixin_34306446的博客 85

c++ 的stl文档_第三期MOOC | STL学习活动

这个学期的第一次程序设计MOOC终于来啦!!!这个学期我们依然会每周更新线上视频课程,课程内容依然会有数学分析和程序设计。同学们的支持是我们最大的动力,希望同学们能多多支持辅助教学项目,也希望我们的课程能对大家的学习有所帮助!!!第一期的程序设计视频由ICPC俱乐部承办,希望同学们看完能够有所收获!先来看看今天的内容!STL学习活动ICPC俱乐部新一期学习活动来了!!!活动介绍...

weixin_32260467的博客 196
上一篇: STL源码分析之hash_multiset配接器
下一篇: STL源码分析之hash_multimap配接器
Function_18
博客等级 码龄10年 193粉丝 239原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值