`
weiyinchao88
  • 浏览: 1194722 次
文章分类
社区版块
存档分类
最新评论

STL的multimap使用(一对多索引)

 
阅读更多
在“使用 <map> 库创建关联容器” 一文中,我们讨论了标准库中的 map 关联容器。但那只是 map 容器的一部分。标准库还定义了一个 multimap 容器,它与 map 类似,所不同的是它允许重复键。这个属性使得 multimap 比预想的要更有用:比如在电话簿中相同的人可以有两个以上电话号码,文件系统中可以将多个符号链接映射到相同的物理文件,或DNS服务器可以将几个URLs映射到相同的IP地址。在这些场合,你可以象下面这样:
// 注: 伪码
multimap <string, string> phonebook;
phonebook.insert("Harry","8225687"); // 家里电话
phonebook.insert("Harry","555123123"); // 单位电话
phonebook.insert("Harry"," 2532532532"); // 移动电话

  在 multimap 中能存储重复键的能力大大地影响它的接口和使用。那么如何创建非唯一键的关联容器呢?答案是使用在 <map> 库中定义的 multimap 容器。

提出问题
  与 map 不同,multimap 可以包含重复键。这就带来一个问题:重载下标操作符如何返回相同键的多个关联值?以下面的伪码为例:

string phone=phonebook["Harry];

  标准库设计者的解决这个问题方法是从 multimap 中去掉下标操作符。因此,需要用不同的方法来插入和获取元素以及和进行错误处理。

插入
   假设你需要开发一个 DNS 后台程序(也就是 Windows 系统中的服务程序),该程序将 IP 地址映射匹配的 URL 串。你知道在某些情况下,相同的 IP 地址要被关联到多个 URLs。这些 URLs 全都指向相同的站点。在这种情况下,你应该使用 multimap,而不是 map。例如:

#include <map>
#include <string>
multimap <string, string> DNS_daemon;

  用 insert() 成员函数而不是下标操作符来插入元素。insert()有一个 pair 类型的参数。在“使用 <map> 库创建关联容器”中我们示范了如何使用 make_pair() 辅助函数来完成此任务。你也可以象下面这样使用它:

DNS_daemon.insert(make_pair("213.108.96.7","cppzone.com"));

  在上面的 insert()调用中,串 “213.108.96.7”是键,“cppzone.com”是其关联的值。以后插入的是相同的键,不同的关联值:

DNS_daemon.insert(make_pair("213.108.96.7","cppluspluszone.com"));

  因此,DNS_daemon 包含两个用相同键值的元素。注意 multimap::insert() 和 map::insert() 返回的值是不同的。

typedef pair <const Key, T> value_type;
iterator
insert(const value_type&); // #1 multimap
pair <iterator, bool>
insert(const value_type&); // #2 map

   multimap::insert()成员函数返回指向新插入元素的迭代指针,也就是 iterator(multimap::insert()总是能执行成功)。但是 map::insert() 返回 pair<iterator, bool>,此处 bool 值表示插入操作是否成功。

查找单个值
  与 map 类似,multimap 具备两个版本重载的 find()成员函数:

iterator find(const key_type& k);
const_iterator find(const key_type& k) const;

find(k) 返回指向第一个与键 k 匹配的 pair 的迭代指针,这就是说,当你想要检查是否存在至少一个与该键关联的值时,或者只需第一个匹配时,这个函数最有用。例如:

typedef multimap <string, string> mmss;
void func(const mmss & dns)
{
mmss::const_iterator cit=dns.find("213.108.96.7");
if (cit != dns.end())
cout <<"213.108.96.7 found" <<endl;
else
cout <<"not found" <<endl;
}

处理多个关联值
  count(k) 成员函数返回与给定键关联的值得数量。下面的例子报告了有多少个与键 “213.108.96.7” 关联的值:

cout<<dns.count("213.108.96.7") //output: 2
<<" elements associated"<<endl;

  为了存取 multimap 中的多个值,使用 equal_range()、lower_bound()和 upper_bound()成员函数:
equal_range(k):该函数查找所有与 k 关联的值。返回迭代指针的 pair,它标记开始和结束范围。下面的例子显示所有与键“213.108.96.7”关联的值:

typedef multimap <string, string>::const_iterator CIT;
typedef pair<CIT, CIT> Range;
Range range=dns.equal_range("213.108.96.7");
for(CIT i=range.first; i!=range.second; ++i)
cout << i->second << endl; //output: cpluspluszone.com
// cppzone.com

   lower_bound() 和 upper_bound():lower_bound(k) 查找第一个与键 k 关联的值,而 upper_bound(k) 是查找第一个键值比 k 大的元素。下面的例子示范用 upper_bound()来定位第一个其键值大于“213.108.96.7”的元素。通常,当键是一个字符串时,会有一个词典编纂比较:

dns.insert(make_pair("219.108.96.70", "pythonzone.com"));
CIT cit=dns.upper_bound("213.108.96.7");
if (cit!=dns.end()) //found anything?
cout<<cit->second<<endl; //display: pythonzone.com

如果你想显示其后所有的值,可以用下面这样的循环:

// 插入有相同键的多个值
dns.insert(make_pair("219.108.96.70","pythonzone.com"));
dns.insert(make_pair("219.108.96.70","python-zone.com"));
// 获得第一个值的迭代指针
CIT cit=dns.upper_bound("213.108.96.7");
// 输出: pythonzone.com,python-zone.com
while(cit!=dns.end())
{
   cout<<cit->second<<endl;
   ++cit;
}
结论
  虽然 map 和 multimap 具有相同的接口,其重要差别在于重复键,设计和使用要区别对待。此外,还要注意每个容器里 insert()成员函数的细微差别。
分享到:
评论

相关推荐

    国内移动端APP月活跃(MAU)Top5000 数据整理

    国内移动端APP月活跃(MAU)Top5000 时间范围:2020年-2022年 具有一定参考价值 csv格式

    和平巨魔跨进成免费.ipa

    和平巨魔跨进成免费.ipa

    数据库管理工具:dbeaver-ce-23.0.4-macos-aarch64.dmg

    1.DBeaver是一款通用数据库工具,专为开发人员和数据库管理员设计。 2.DBeaver支持多种数据库系统,包括但不限于MySQL、PostgreSQL、Oracle、DB2、MSSQL、Sybase、Mimer、HSQLDB、Derby、SQLite等,几乎涵盖了市场上所有的主流数据库。 3.支持的操作系统:包括Windows(2000/XP/2003/Vista/7/10/11)、Linux、Mac OS、Solaris、AIX、HPUX等。 4.主要特性: 数据库管理:支持数据库元数据浏览、元数据编辑(包括表、列、键、索引等)、SQL语句和脚本的执行、数据导入导出等。 用户界面:提供图形界面来查看数据库结构、执行SQL查询和脚本、浏览和导出数据,以及处理BLOB/CLOB数据等。用户界面设计简洁明了,易于使用。 高级功能:除了基本的数据库管理功能外,DBeaver还提供了一些高级功能,如数据库版本控制(可与Git、SVN等版本控制系统集成)、数据分析和可视化工具(如图表、统计信息和数据报告)、SQL代码自动补全等。

    【课件】8.4.1简单选择排序.pdf

    【课件】8.4.1简单选择排序

    写的一个静态网站随便写的

    写的一个静态网站随便写的写的一个静态网站随便写的写的一个静态网站随便写的写的一个静态网站随便写的写的一个静态网站随便写的写的一个静态网站随便写的写的一个静态网站随便写的

    Java项目-基于SSM+JSP的教学质量评价系统的设计与实现(源码+万字LW+部署视频+代码讲解视频+全套软件)

    【基于SSM+JSP的教学质量评价系统的设计与实现】高分通过项目,已获导师指导。 本项目是一套基于SSM+JSP的教学质量评价系统,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的Java学习者。也可作为课程设计、期末大作业 包含:项目源码、数据库脚本、开发说明文档、部署视频、代码讲解视频、全套软件等,该项目可以直接作为毕设使用。 项目都经过严格调试,确保可以运行! 项目详情: https://blog.csdn.net/u011832806/article/details/139522897

    TbReactions(BaseModel)

    TbReactions(BaseModel)

    C++ 算法教程,贝塞尔曲线计算

    C++ 算法教程,贝塞尔曲线计算

    AGV语音播报V2.1.wav

    AGV语音播报V2.1.wav

    comment.block.documentation.rust

    comment.block.documentation.rust

    c语言怎么连接两个字符串.pdf

    c语言连接两个字符串

    af911f51-9..._lan.zip

    af911f51-9..._lan

    【无人车路径规划】frenet-path-planning.zip

    无人车 无人车路径搜索,是一个比较复杂的问题,但是要入门无人车路径规划或者路径搜索,需要先掌握一些基础的东西。不同于机器人中经常看到的路径规划(比如ROS中基于costmap)算法,无人车的路径搜索算法更加先进,它将考虑的东西更多,那么我们先从最简单的开始。 以一根曲线为参照线,定义坐标系的纵轴为前进方向(s), 横轴为与s法线向量垂直的向量,从而构成Frenet坐标系,那么为什么我们规划无人车轨迹不采用迪卡尔坐标系呢?原因很简单,Frenet坐标系明显更简单,更适合我们处理无人车的路径规划问题。 我们可以将路径规划在Frenet的基础上进行分解,比如,专门求解在s方向,也就是纵向的最优路径,求解在d方向也就是横向的最优解,从而形成合成的最优化轨迹。

    FastStone Capture屏幕长截图软件包

    FastStone Capture屏幕长截图软件包

    学习数据结构和算法.zip

    大学生数据结构学习笔记和资料大全!

    数据库管理工具:dbeaver-ce-24.0.2-stable.x86-64.rpm

    1.DBeaver是一款通用数据库工具,专为开发人员和数据库管理员设计。 2.DBeaver支持多种数据库系统,包括但不限于MySQL、PostgreSQL、Oracle、DB2、MSSQL、Sybase、Mimer、HSQLDB、Derby、SQLite等,几乎涵盖了市场上所有的主流数据库。 3.支持的操作系统:包括Windows(2000/XP/2003/Vista/7/10/11)、Linux、Mac OS、Solaris、AIX、HPUX等。 4.主要特性: 数据库管理:支持数据库元数据浏览、元数据编辑(包括表、列、键、索引等)、SQL语句和脚本的执行、数据导入导出等。 用户界面:提供图形界面来查看数据库结构、执行SQL查询和脚本、浏览和导出数据,以及处理BLOB/CLOB数据等。用户界面设计简洁明了,易于使用。 高级功能:除了基本的数据库管理功能外,DBeaver还提供了一些高级功能,如数据库版本控制(可与Git、SVN等版本控制系统集成)、数据分析和可视化工具(如图表、统计信息和数据报告)、SQL代码自动补全等。

    神奇翻转源码Introduction_to_Computation.zip

    神奇翻转源码Introduction_to_Computation.zip

    毕设项目:企业员工信息管理系统的设计与实现(ASP.NET技术+源代码+文档)

    1 引言 1 1.1 课题背景 1 1.2 国内外研究现状 1 1.3 本课题研究的意义 1 1.4 本课题的研究方法 2 2 理论基础 2 2.1 开发语言及软件简介 2 2.2 开发环境介绍 4 3 系统需求分析 4 3.1 系统总体需求分析 4 3.2 系统可行性分析 5 4 系统总体设计 5 4.1 系统功能规划 5 4.2 系统设计目标 6 4.2.1 系统功能总体设计目标 6 4.2.2 系统功能模块概述 6 4.2.3 系统功能模块图 7 4.3 系统数据库设计 8 5 系统实现 13 5.1 登录模块 13 5.2 信息管理模块 14 5.2.1员工信息管理模块 14 5.2.2 管理员端信息管理模块 16 5.3 消息管理模块 17 5.3.1 员工端消息管理模块 18 5.3.2 管理员端消息管理模块 21 5.4 薪酬模块 21 5.4.1 员工端薪酬模块 21 5.4.2 管理员端薪酬模块 22 6 系统测试 23 6.1测试环境 23 6.2 测试过程 23 6.3测试结果 23 结 论 24 参考文献 24 致 谢 25 声 明 26

    应用开发-画布技术-时钟-功能性小程序-画布时钟小程序.zip

    本资源提供了一个基于画布技术的时钟小程序开发指南和完整源码,该小程序展示了如何使用HTML5 Canvas或微信小程序的画布API来创建一个功能性的时钟。这个时钟小程序不仅提供时间显示,还能作为学习如何在小程序中使用画布技术的示例。 主要特点: 实时时钟显示:提供模拟和数字时钟的实时时间显示。 自定义设计:允许用户自定义时钟的外观,包括颜色、字体和布局。 高度交互性:用户可以通过触摸操作调整时钟设置或切换不同的显示模式。 图形渲染:利用画布技术绘制精确的时钟指针和数字,确保视觉效果的精准和美观。 技术实现: 前端技术:基于微信小程序的Canvas API,结合JavaScript进行动态图形的绘制和更新。 性能优化:优化画布渲染流程,确保时钟更新流畅且不会消耗过多资源。 用户界面友好:设计直观的用户界面,使得非技术用户也能轻松使用和配置时钟。 应用场景: 个性化设备:适用于需要个性化时钟显示的用户,如在个人主页或工作站展示。 教育目的:可用于编程和图形设计的教学,特别是在教授相关的图形编程技术。 功能性插件:可以集成到更大的应用程序中,提供时间显示功能。 通过使用这个画布时钟小程序,

    数据库管理工具:dbeaver-ce-23.2.2-amd64.deb

    1.DBeaver是一款通用数据库工具,专为开发人员和数据库管理员设计。 2.DBeaver支持多种数据库系统,包括但不限于MySQL、PostgreSQL、Oracle、DB2、MSSQL、Sybase、Mimer、HSQLDB、Derby、SQLite等,几乎涵盖了市场上所有的主流数据库。 3.支持的操作系统:包括Windows(2000/XP/2003/Vista/7/10/11)、Linux、Mac OS、Solaris、AIX、HPUX等。 4.主要特性: 数据库管理:支持数据库元数据浏览、元数据编辑(包括表、列、键、索引等)、SQL语句和脚本的执行、数据导入导出等。 用户界面:提供图形界面来查看数据库结构、执行SQL查询和脚本、浏览和导出数据,以及处理BLOB/CLOB数据等。用户界面设计简洁明了,易于使用。 高级功能:除了基本的数据库管理功能外,DBeaver还提供了一些高级功能,如数据库版本控制(可与Git、SVN等版本控制系统集成)、数据分析和可视化工具(如图表、统计信息和数据报告)、SQL代码自动补全等。

Global site tag (gtag.js) - Google Analytics