使用 库创建关联容器
2007-04-17 19:23
344 查看
关系数据库,科学计算应用以及基于Web的系统常常需要类似 vector 的容器,其索引可以是如何数据类型,不一定是整数。这样的容器叫关联容器,或者 map。例如,目录服务应用可以将私人姓名作为索引来存储,电话号码作为其关联的值:
其它关联容器的应用还包括将 URLs 映射到 IP 的 DNS 服务器,字典,库存清单,工资表等等。那么如何突破整型索引的局限,实现用其它数据类型作为索引的关联容器呢?答案是:使用 <map> 库创建和处理关联容器。
Pair 和 Map
最近的一篇文章中,我介绍了 tuple 的概念,它是不同类型元素的集合。在这篇文章中,有一个内容没有提到,那就是 C++98 标准库已经具备一个特殊的 tuple 类型——pair。它将键值(也就是第一个元素)与某个值(第二个值)关联。例如:
标准库还定义了一个辅助函数,方便 pair 类型的创建:
第一步:构造和初始化一个 map 对象
假设你正在开发一个地址簿程序,地址簿包含姓名和 e-mail 地址。类模板 map 在 <map> 中定义i,它是一个使用类型对的关联容器,第一个元素是索引,第二个元素是关联的值。使用方法如下:
为了添加元素,使用下标算符:
这里,串“Paul W.”是索引或键值,“paul@mail.com”是其关联的值。如果该 map 已经包含了此键值,那么当前所关联的值不会改变:
第二步:搜索
在不插入元素的情况下,如果你想检查某个元素是否存在,可以使用 find()成员函数。find()有两个重载的版本:
通常,用 typedef 可以使代码更可读一些:
表达式中 cit->first 和 cit->second 分别返回键值及其关联的值。
第三步:元素遍历
现在让我们看一个更现实的情况。假设你正在经营一家旅行社,每一个代理做一单业务都可以获得奖金。这些代理的信息存储在某个文件中,其格式如下:
你的应用程序必须汇总所有代理的奖金并将每个代理的奖金总数显示出来.首先,创建一个 map,然后读取该数据文件:
不管理相不相信,就这么简单!且让我们来分析一下该循环。打开数据文件之后,while 循环读取每个值对,并将其存入 agent 和 bouns 对象。接着,它将 agent 和 bouns 插入到该 map。此处的关键技巧是:如果键值(agent)已经存在,那么 += 操作符便将最新读取的 bouns 累加到存储在 map 中当前的 bouns 中。因为表达式:
返回与键值关联的值。当重载的 += 操作符被调用时,该值便被累加到新读取的 bouns 中。最后累加的和覆盖 map 中旧的关联值。记住:当你使用下标算符机制时,纯粹的赋值操作并不会改写现有的值,只有重载的 += 才这么做。
幸运的是,map 并不包含一个必须要初始化的键值,表达式:
返回默认的初始化 T,而 T 在上述例子中是 double 类型。默认的初始值为 0。至此,map 包含代理及其奖金汇总值对。下面的循环用来显示这些值对,输出如图一所示:
图一 代理奖金汇总数
散列的关联容器
标准库目前还不提供散列关联容器。这种容器可以大大改进性能,因为它们使用散列算法从原来的字符串索引派生短键值。但是,许多 IDEs 提供非标准散列容器扩展。值得庆幸的是,新的 C++0X 标准弥补了这一点,在 C++ 中添加了一组散列容器和与之相关的算法。
其它关联容器的应用还包括将 URLs 映射到 IP 的 DNS 服务器,字典,库存清单,工资表等等。那么如何突破整型索引的局限,实现用其它数据类型作为索引的关联容器呢?答案是:使用 <map> 库创建和处理关联容器。
Pair 和 Map
最近的一篇文章中,我介绍了 tuple 的概念,它是不同类型元素的集合。在这篇文章中,有一个内容没有提到,那就是 C++98 标准库已经具备一个特殊的 tuple 类型——pair。它将键值(也就是第一个元素)与某个值(第二个值)关联。例如:
标准库还定义了一个辅助函数,方便 pair 类型的创建:
第一步:构造和初始化一个 map 对象
假设你正在开发一个地址簿程序,地址簿包含姓名和 e-mail 地址。类模板 map 在 <map> 中定义i,它是一个使用类型对的关联容器,第一个元素是索引,第二个元素是关联的值。使用方法如下:
为了添加元素,使用下标算符:
这里,串“Paul W.”是索引或键值,“paul@mail.com”是其关联的值。如果该 map 已经包含了此键值,那么当前所关联的值不会改变:
第二步:搜索
在不插入元素的情况下,如果你想检查某个元素是否存在,可以使用 find()成员函数。find()有两个重载的版本:
通常,用 typedef 可以使代码更可读一些:
表达式中 cit->first 和 cit->second 分别返回键值及其关联的值。
第三步:元素遍历
现在让我们看一个更现实的情况。假设你正在经营一家旅行社,每一个代理做一单业务都可以获得奖金。这些代理的信息存储在某个文件中,其格式如下:
你的应用程序必须汇总所有代理的奖金并将每个代理的奖金总数显示出来.首先,创建一个 map,然后读取该数据文件:
不管理相不相信,就这么简单!且让我们来分析一下该循环。打开数据文件之后,while 循环读取每个值对,并将其存入 agent 和 bouns 对象。接着,它将 agent 和 bouns 插入到该 map。此处的关键技巧是:如果键值(agent)已经存在,那么 += 操作符便将最新读取的 bouns 累加到存储在 map 中当前的 bouns 中。因为表达式:
返回与键值关联的值。当重载的 += 操作符被调用时,该值便被累加到新读取的 bouns 中。最后累加的和覆盖 map 中旧的关联值。记住:当你使用下标算符机制时,纯粹的赋值操作并不会改写现有的值,只有重载的 += 才这么做。
幸运的是,map 并不包含一个必须要初始化的键值,表达式:
返回默认的初始化 T,而 T 在上述例子中是 double 类型。默认的初始值为 0。至此,map 包含代理及其奖金汇总值对。下面的循环用来显示这些值对,输出如图一所示:
图一 代理奖金汇总数
散列的关联容器
标准库目前还不提供散列关联容器。这种容器可以大大改进性能,因为它们使用散列算法从原来的字符串索引派生短键值。但是,许多 IDEs 提供非标准散列容器扩展。值得庆幸的是,新的 C++0X 标准弥补了这一点,在 C++ 中添加了一组散列容器和与之相关的算法。
相关文章推荐
- 使用 库创建重复键关联容器
- 使用 <map> 库创建关联容器
- 使用map库创建关联容器
- 使用multimap创建重复键关联容器
- 使用 MAP CLASS 库创建关联容器
- 使用 库创建关联容器
- 使用 库创建重复键关联容器
- Spring 容器创建 依赖注入 web整合 注解使用
- C++中防止STL中迭代器失效——map/set等关联容器——vector/list/deque等序列容器—如何防止迭代器失效—即erase()的使用
- 使用docker 拉取镜像和创建容器-nginx
- docker-3-使用dockerfile创建容器
- 手动创建(new)对象,使用spring容器中的bean(ServletContext)。
- 2. 使用Spring容器创建bean
- 使用C#在程序运行时创建文件关联
- 使用Dockerfile创建nginx服务容器镜像
- 使用navicat创建MySQL外键关联
- C++之STL中常用关联容器使用方法
- 使用Rancher创建负载均衡的容器应用
- map等关联容器 vector等序列容器 如何防止迭代器失效 即erase()的使用