SGISTL源码探究-关联式容器:hash_multimap

别再只抄代码了!深入理解MQ2传感器数据手册,搞定ppm换算公式 本文深入解析MQ2烟雾传感器的工作原理与ppm换算公式,从数据手册解读到数学建模,提供详细的校准与优化方法。通过实际案例和代码示例,帮助开发者准确测量气体浓度,解决常见问题,提升传感器应用的可靠性。 阅读详情

前言

本小节将介绍hash_multimap的源码实现,它与hash_map的不同与map和multimap的不同类似,所以我们可以一边分析它们的不同之处,一边顺便复习hash_map。

hash_multimap的实现

定义及数据结构
#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_multimap
{
private:
  //这里不要忽视了pair的第一个元素是const型的,不允许修改
  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(); }
构造函数
public:
  /* 构造函数 指定大小、哈希函数、比较key大小的函数 */
  hash_multimap() : rep(100, hasher(), key_equal()) {}
  explicit hash_multimap(size_type n) : rep(n, hasher(), key_equal()) {}
  hash_multimap(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
  hash_multimap(size_type n, const hasher& hf, const key_equal& eql)
    : rep(n, hf, eql) {}

  //插入元素时使用的insert_equal
#ifdef __STL_MEMBER_TEMPLATES
  template <class InputIterator>
  hash_multimap(InputIterator f, InputIterator l)
    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
  template <class InputIterator>
  hash_multimap(InputIterator f, InputIterator l, size_type n)
    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
  template <class InputIterator>
  hash_multimap(InputIterator f, InputIterator l, size_type n,
                const hasher& hf)
    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
  template <class InputIterator>
  hash_multimap(InputIterator f, InputIterator l, size_type n,
                const hasher& hf, const key_equal& eql)
    : rep(n, hf, eql) { rep.insert_equal(f, l); }

#else
  hash_multimap(const value_type* f, const value_type* l)
    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
  hash_multimap(const value_type* f, const value_type* l, size_type n)
    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
  hash_multimap(const value_type* f, const value_type* l, size_type n,
                const hasher& hf)
    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
  hash_multimap(const value_type* f, const value_type* l, size_type n,
                const hasher& hf, const key_equal& eql)
    : rep(n, hf, eql) { rep.insert_equal(f, l); }

  hash_multimap(const_iterator f, const_iterator l)
    : rep(100, hasher(), key_equal()) { rep.insert_equal(f, l); }
  hash_multimap(const_iterator f, const_iterator l, size_type n)
    : rep(n, hasher(), key_equal()) { rep.insert_equal(f, l); }
  hash_multimap(const_iterator f, const_iterator l, size_type n,
                const hasher& hf)
    : rep(n, hf, key_equal()) { rep.insert_equal(f, l); }
  hash_multimap(const_iterator f, const_iterator l, size_type n,
                const hasher& hf, const key_equal& eql)
    : rep(n, hf, eql) { rep.insert_equal(f, l); }
#endif /*__STL_MEMBER_TEMPLATES */
常用操作
public:
  //这部分都与hash_map相同
  size_type size() const { return rep.size(); }
  size_type max_size() const { return rep.max_size(); }
  bool empty() const { return rep.empty(); }
  void swap(hash_multimap& hs) { rep.swap(hs.rep); }
  friend bool
  operator== __STL_NULL_TMPL_ARGS (const hash_multimap&, const hash_multimap&);

  //返回首/尾迭代器,尾迭代器为指向null的节点的指针,首迭代器为指向第一个bucket不为空的头节点的指针
  iterator begin() { return rep.begin(); }
  iterator end() { return rep.end(); }
  const_iterator begin() const { return rep.begin(); }
  const_iterator end() const { return rep.end(); }

public:
  //插入操作,调用的是insert_equal
  iterator insert(const value_type& obj) { return rep.insert_equal(obj); }
#ifdef __STL_MEMBER_TEMPLATES
  template <class InputIterator>
  void insert(InputIterator f, InputIterator l) { rep.insert_equal(f,l); }
#else
  void insert(const value_type* f, const value_type* l) {
    rep.insert_equal(f,l);
  }
  void insert(const_iterator f, const_iterator l) { rep.insert_equal(f, l); }
#endif /*__STL_MEMBER_TEMPLATES */
  iterator insert_noresize(const value_type& obj)
    { return rep.insert_equal_noresize(obj); }    

  iterator find(const key_type& key) { return rep.find(key); }
  const_iterator find(const key_type& key) const { return rep.find(key); }
  /* 在hash_map中,这里实现了对[]操作符的重载
   * 但是在hash_multimap中没有对其重载
   * 是因为key可以重复,那么下标访问时可能就对应了多个元素,此时该返回哪个就成了难题
   */
  size_type count(const key_type& key) const { return rep.count(key); }

  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:
  /* 剩下的部分都与hash_map相同了 */
  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); }
};

template <class Key, class T, class HF, class EqKey, class Alloc>
inline bool operator==(const hash_multimap<Key, T, HF, EqKey, Alloc>& hm1,
                       const hash_multimap<Key, T, HF, EqKey, Alloc>& hm2)
{
  return hm1.rep == hm2.rep;
}

#ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER

template <class Key, class T, class HashFcn, class EqualKey, class Alloc>
inline void swap(hash_multimap<Key, T, HashFcn, EqualKey, Alloc>& hm1,
                 hash_multimap<Key, T, HashFcn, EqualKey, Alloc>& hm2)
{
  hm1.swap(hm2);
}

#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */

小结

本小节对hash_multimap进行了分析。它和hash_map的不同之处除了插入元素时允许重复之外,hash_multimap还不支持下标运算。
关联式容器部分就到此为止了,其实只要把hashtable的实现搞明白了,对hash_set和hash_map之类的理解就轻松多了。
在下一小节中,我们将对STL中的泛型算法部分开始分析,在具体的源码分析中,我不会列出所有的算法,而是选择其中比较经典和常用的算法进行分析。

实战指南:在摩尔线程GPU上部署AI模型的完整流程 本文提供了一份详尽的实战指南,手把手教你如何在摩尔线程GPU上成功部署AI模型。内容涵盖从驱动安装、Docker环境配置,到核心的代码适配与模型运行全流程,并分享了性能调优技巧与常见避坑方法,旨在帮助开发者高效利用国产硬件进行AI应用开发。 阅读详情

相关推荐

不用敲命令!用宝塔面板可视化部署pbootCMS的保姆级教程(2024最新版)

本文提供2024年最新版pbootCMS可视化部署教程,全程使用宝塔面板操作,无需任何命令行知识。从服务器初始化、LNMP环境配置到源码上传、安装向导,手把手指导用户通过图形化界面快速搭建专业网站,适合零基础新手和追求高效建站的用户。

weixin_42509507的博客 490

关联式容器——hash_map和hash_multimap

hash_map STL map多半以RB-tree为底层实现。SGI则是在STL标准规格之外又提供了一个所谓的hash_map,以hash_table为底层实现机制。由于hash_map所提供的操作接口,hashtable都提供了,所以几乎所有hash_map操作行为,都只是调用hashtable的操作而已。运用map,为的是能够根据键值快速搜寻元素。这一点,不论底层是红黑树还是...

一个小孩 360

Matlab蒙特卡洛模拟二维伊辛模型相变过程

一、什么是伊辛模型 伊辛(Ising)模型是描述磁系统相变最简单的模型,但模型里自旋之间的相互作用赋予了它奇妙的特性,最有趣的就是对称性破缺。这一模型可以被推广用于研究连续的量子相变、基本粒子超弦理论、动力学临界行为等,甚至被认为可以描述深林火灾、交通拥堵、舆论传播等社会经济现象。 如图,每个格点的方向只有向上或向下两者状态,但临近的自旋之间有相互作用,而且点阵可以是一维、二维、三维、甚至更高维...

http://www.icfgblog.com/ 2万+

STL源码剖析——hash_map和hash_multimap

SGI STL中的map底层以红黑树实现,hash_map以hash table实现。 hash_map不允许插入重新键值,hash_multimap允许插入重复键值。这两者的关系就像map和multimap的关系。底层的hash table提供的大部分的操作,hash_map(hash_multimap)大部分都是直接调用hash table的函数。 hash_multimap和ha

Smile&搁浅 1854

从理论到实践:基于Zemax的高分辨率生物显微镜光学系统仿真与优化指南

本文详细介绍了基于Zemax的高分辨率生物显微镜光学系统仿真与优化全流程。从阿贝分辨率公式、柯勒照明等理论基础出发,逐步讲解Zemax建模、像差优化、制造可行性分析等核心步骤,并提供常见问题解决方案。通过实际案例展示如何将理论设计转化为可制造的优化方案,帮助工程师掌握从仿真到实际应用的关键技术。

weixin_29229989的博客 481

【33】软考软件设计师——算法题(二):贪心法与回溯法深度精讲|第4题进阶满分攻略

本文是《软件设计师·50讲通关|从零基础到工程师职称》专栏第33篇,承接第32篇分治法与动态规划,聚焦**下午第4题算法大题进阶核心**,详解贪心法与回溯法两大高频难点算法。全文超4000字深度拆解贪心法核心原理、贪心选择性质、局部最优推全局最优的底层逻辑,厘清贪心算法适用边界与经典误区;深挖回溯法深度优先遍历思想、递归回溯三步流程、可行性剪枝与最优性剪枝两大核心技巧;全覆盖活动选择、零钱兑换、01背包贪心禁区、八皇后、全排列等软考必考经典题型;配套标准化算法框架代码、考场填空模板、剪枝优化实操案例

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 439

STL之hash_set和hash_multiset、hash_map和hash_multimap详解

hash_set 1、介绍 虽然STL只规范复杂度和接口,并不规范实现方法,但STL set多半以RB-tree为底层机制。 SGI在标准之外提供了hash_set,以hashtable作为底层机制。用set为的是能快速搜寻元素。这一点无论底层是RB-tree还是hashtable都能实现。但RB-tree有自动排序能力(二叉树特性)而hashtable(肯定没有啊)没有,其结果就是set元...

一个菜鸟的博客 1000

华为OD机试2025C卷 - 精准核酸检测 (C++ & Python & JAVA & JS & GO)

华为OD机试2025C卷 精准核酸检测,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解

qq_45776114的博客 1707

hash_set, hash_map,hash_multiset,hash_multimap

hash_set STL set多半以RB-TREE为底层机制。SGI在STL标准规格之外又提供了一个所谓的hash_set,以hashtable为底层机制。 RB-TREE有自动排序功能而hashtable没有,反应出来的结果就是,set的元素有自动排序功能而hash_set没有。 凡是hashtable无法处理者,hash_set也无法处理。 hash_map SGI在STL标准规格之外,另提供了一个所谓的hash_map,以hashtable为底层机制。由于hash_map所供应的操作接口,hasht

qq_36553387的博客 355

网格质量评价

CFD中评价网格质量的方法

B_etter_Man的博客 1万+

CloudCompare 多窗口联动显示点云

CloudCompare支持多窗口联动显示多个点云数据,可以用来比对原始点云数据与语义分割后的结果。 一、创建多个视窗 打开CloudCompare后会默认有一个视图,我们要同时打开两个数据就需要再创建一个视图,选择菜单栏里的3D Views,在下拉菜单中点击new,这样就创建了一个新的视图,这时3D Views的下拉菜单中有3D View 1和3D View 2两个视图,然后点击3D Views下拉菜单中的Title,这时在数据展示区就会出现两个并列的窗口。 二、分别加载点云数据 将数据分别拖进两个

zhaoguanhua的博客 2739

SGISTL源码阅读二十五 hash_map 关联式容器

SGISTL源码阅读二十五 hash_map 关联式容器 前言 前面我们已经分析了底层容器为红黑树的map和hashtable,而接下来我们要分析的hash_map,其底层容器为hashtable。 深入源码 hash_map的定义部分 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES template &amp;lt;class Key, class T, class H...

Lyn&Xx 232

【人工智能 Open AI】程序员怎样提升研发效率?从技术、业务、项目管理等等多个方面来阐述。

程序员要想提升研发效率,需要从技术、业务、项目管理等多方面着手,多靠工具配合实践实现,从而提升研发效率。

AI天才研究院 5526

SGISTL源码-容器 笔记

本文是在阅读SGI STL v3.3源码中,遇到的一些问题及有意思的点。本文建立在已经观看过侯捷老师STL源码剖析课程的基础上。是在阅读源码过程中,对其中的内容进行补充、修饰。

weixin_46065476的博客 596

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

《STL源码剖析》——第五、六章:关联容器与算法

第五章、关联容器 5.0、关联容器 标准的STL关联式容器分为set(集合)和map(映射表)两大类,以及这两大类的衍生体multiset(多键集合)和multimap(多键映射表)。这些容器的底层机制均以RB-tree(红黑树)完成。RB-tree也是一个独立容器,但并不开放给外界使用。 SGISTL还提供了一个不在标准规格之列的关联式容器:hash_table(散列表),以及以此has...

weixin_42637495的博客 350

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

map和set

1. set是按照一定次序存储元素的容器2. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行 排序。4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对 子集进行直接迭代。

weixin_66400112的博客 1331

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

stl之hash_multimap

hash_multimap的元素不能自动排序

雪儿的专栏 1209

STL源码剖析 - 第5章 关联式容器 - hash_multimap

5.11 hash_multimap        hash_multimap和hash_map的区别就像multimap与map的区别一样,hash_multimap的底层机制是基于hashtable,它可以存在重复的键值,所以插入函数使用insert_equal(),hash_multimap和hash_map一样,容器的内容不自动排序。本文源码出自SGI STL的文件。 hash_mul

灯火阑珊处 744

STL源码分析之hash_multimap配接器

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

啦啦啦 555

STL源码剖析-hash_map / hash_multimap

类似于标准的map以rb_tree为底层实现,hash_map以hashtable为底层实现,hash_map的底层操作也是由hashtabe提供。 运用map,为的是能够快速的根据key搜索元素。这一点无论其底层是rb_tree或是hashtable,都可以达成任务。但是rb_tree有自动排序的功能,而hashtable是没有,反应的结果是map元素有自动排序功能,而hash_map没有。 ...

常思考->有目标->重实践->善反思 992

hash_set,hash_map,hash_multiset,hash_multimap

上面四中容器都基于hashtable这种底层的机制。

了解的越多,越知道自己的无知 1519

C++STL之hash_table,hash_map与hash_multimap,hash_set与hash_multiset的使用

hash_table是STL中hash_map 和 hash_set 的内部数据结构,hash_table的插入 / 删除 / 查找的时间复杂度都为O(1), 是查找速度最快的一种数据结构,但是hash_table中的数据是无序的,一般也只有在数据不需要排序, 只需要满足快速查找 / 插入 / 删除的时候使用hash_table。hash_table的扩展是将原hash_table中的数据摘下来插...

Alexander的博客 1584

multimap , hash_multimap

http://wwwasd.web.cern.ch/wwwasd/lhc++/ObjectSpace/doc/2.1/stdusr/http://wwwasd.web.cern.ch/wwwasd/lhc++/ObjectSpace/doc/2.1/stdusr/1stclass.9.html A multimap is an associative container that ma

杨德龙的专栏 5867

三 关联式容器(五)hash_map与hash_multimap

一 hash_map定义: (1)hash_map以hashtable为底层机制,几乎所有hash_map的接口都是调用hashtable的接口来实现的。 (2)实现文件中hash_map的定义: template class hash_multimap { private:   typedef hashtable, _Key, _HashFcn,

linux系统、网络编程和分布式计算 1195

guava中Multimap、HashMultimap使用详解

在介绍Multimap之前我们先说一下Map,Map是一个key、value类型的键值对集合,集合中key不可以重复,但value可以重复,如果我们想在Map集合中存入一个相同的key,不同的value值得时候就必须使用Map&amp;amp;amp;amp;lt;Integer,List&amp;amp;amp;amp;lt;Object&amp;amp;amp;amp;gt;&amp;amp;amp;amp;gt;Map&amp;amp;amp;amp;lt;In

OceanSky的专栏 2万+

hash_multimap的源码

hash_multimap的特性与multimap完全相同,唯一的差别在于它的底层机制是hashtable,也因此,hash_multimap 的元素不会被自动排序 hash_multimap与hash_map的唯一差别就在于,前者的元素插入操作采用insert_equal,而后者采用 insert_unique hashtable无法处理元素型别,hash_mutimap也没有办法处理 tem...

Zyong139064359的博客 275
上一篇: SGISTL源码探究-关联式容器:hash_multiset
下一篇: SGISTL源码探究-STL中的算法(前言)
UKey_
博客等级 码龄10年 258粉丝 186原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值