#include <string> #include <map>
using namespace std;
int main()
{
map<string, int> word_count;
map<string, int>::iterator map_it = word_count.begin();
word_count["Hello"] = 2222; //通过键来访问元素,注意:如果没有这个键时,就会自动创建
cout << word_count["Hello"] << endl;
word_count["Hello"] += 3444;
cout << word_count["Hello"] << endl;
return 0;
}
资料:
1.映射和多重映射以容器以键/值对(pair对象)的形式管理他们的元素,其元素按照
某种标准对键进行排列,默认标准为 <.排序时比较pair对象的数据成员first的值.
相等则比较second的值.
2.映射和多重映射
二者惟一区别:映射(map)不允许重复,多重映射(multimap)允许.
使用两种容器必须包含#include <map>
3.构造函数
ctType <key,Type> ct; 创建空的映射或多重映射,排序标准' <'
ctType <key,Type,sortOp> ct; ..................排序标准'sortOp'
ctType <key,Type> ct(otherCt); 创建ct,元素从ohterCt复制(排序标准为 <)
ctType <key,Type,sortOp> ct(ohterCt); ...(两容器排序标准都为sortOp)
ctType <key,Type> ct(beg,end); 创建ct,迭代器beg,end-1之间的元素复制给ct
ctType <key,Type,sortOp> ct(beg,end); . ..............(排序标准为sortOp)
eg:map <int,int,greater <int> > ss(beg,end)//注意要放空格
3.常用函数
insert(e) 把e插入ct中,若ct是映射,它还会返回插入操作是否成功
注:e为pair对象
insert(pos,e) 把e插入ct中,返回e插入位置,迭代器pos指定搜索插入点的位置
insert(beg,end) 复制beg和end-1之间所有元素插入到ct中
erase(e) 删除所有值为e的元素,返回被删除元素的数目
注:只能输入某个pair对象的first的值,删除该对象
erase(pos) 删除pos指定位置的元素,无返回值
erase(beg,end) 删除beg和end-1之间的元素,无返回值
clear() 删除ct中所有元素,经此操作,容器ct为空
find(e) 返回指向第一个等于e的元素位置的迭代器,没有则返回ct.end()
注:只能输入某个pair对象的first的值为条件进行查找
eg:cout < <mm.find(25)->first;
摘要:当索引是整型,那么将值与之关联并不难,但如果数据的关联值对是其它数据类型怎么办呢?<map>库具备一个关联容器,使用它可以很方便地关联所有类型的数据对。本文将讨论 <map> 库的使用方法和技巧。 |
关系数据库,科学计算应用以及基于Web的系统常常需要类似 vector 的容器,其索引可以是如何数据类型,不一定是整数。这样的容器叫关联容器,或者 map。例如,目录服务应用可以将私人姓名作为索引来存储,电话号码作为其关联的值:
directory["Harry"]=8225687;// 插入 "Harry" 并与他的电话号码关联 iterator it=directory.find("Harry");// 获取 Harry 的电话号码
其它关联容器的应用还包括将 URLs 映射到 IP 的 DNS 服务器,字典,库存清单,工资表等等。那么如何突破整型索引的局限,实现用其它数据类型作为索引的关联容器呢?答案是:使用 <map> 库创建和处理关联容器。
Pair 和 Map
最近的一篇文章中,我介绍了 tuple 的概念,它是不同类型元素的集合。在这篇文章中,有一个内容没有提到,那就是 C++98 标准库已经具备一个特殊的 tuple 类型——pair。它将键值(也就是第一个元素)与某个值(第二个值)关联。例如:
#include <utility> //definition of pair #include <string> pair <string, string> prof_and_course("Jones", "Syntax"); pair <int, string> symbolic_const (0, "false");
标准库还定义了一个辅助函数,方便 pair 类型的创建:
string prof; string course; make_pair(prof,course);//returns pair <string,string>
第一步:构造和初始化一个 map 对象
假设你正在开发一个地址簿程序,地址簿包含姓名和 e-mail 地址。类模板 map 在 <map> 中定义i,它是一个使用类型对的关联容器,第一个元素是索引,第二个元素是关联的值。使用方法如下:
#include <map> map <string, string> addresses;
为了添加元素,使用下标算符:
addresses["Paul W."]="paul@mail.com";
这里,串“Paul W.”是索引或键值,“paul@mail.com”是其关联的值。如果该 map 已经包含了此键值,那么当前所关联的值不会改变:
addresses["Paul W."]= "newaddr@com.net"; // 不起作用
第二步:搜索
在不插入元素的情况下,如果你想检查某个元素是否存在,可以使用 find()成员函数。find()有两个重载的版本:
iterator find(const key_type& k); const_iterator find(const key_type& k) const;
通常,用 typedef 可以使代码更可读一些:
typedef map <string, string>::const_iterator CIT; CIT cit=addresses.find("Paul W."); if (cit==addresses.end()) cout << "sorry, no such key" << endl; else cout << cit->first << ''\t'' << cit->second << endl;
表达式中 cit->first 和 cit->second 分别返回键值及其关联的值。
第三步:元素遍历
现在让我们看一个更现实的情况。假设你正在经营一家旅行社,每一个代理做一单业务都可以获得奖金。这些代理的信息存储在某个文件中,其格式如下:
Bob 35 Bob 90 Jane 80.25 Sue 100 Jane 65.5
你的应用程序必须汇总所有代理的奖金并将每个代理的奖金总数显示出来.首先,创建一个 map,然后读取该数据文件:
map <string, double> bonuses; string agent; double bonus=0; ifstream bonusfile("bonuses.dat"); if(!bonusfile) { // 报告出错信息并终止程序 } while (bonusfile >> agent >> bonus) { bonuses[agent]+=bonus;// 累加每个代理的奖金 }
不管理相不相信,就这么简单!且让我们来分析一下该循环。打开数据文件之后,while 循环读取每个值对,并将其存入 agent 和 bouns 对象。接着,它将 agent 和 bouns 插入到该 map。此处的关键技巧是:如果键值(agent)已经存在,那么 += 操作符便将最新读取的 bouns 累加到存储在 map 中当前的 bouns 中。因为表达式:
map[key]
返回与键值关联的值。当重载的 += 操作符被调用时,该值便被累加到新读取的 bouns 中。最后累加的和覆盖 map 中旧的关联值。记住:当你使用下标算符机制时,纯粹的赋值操作并不会改写现有的值,只有重载的 += 才这么做。
幸运的是,map 并不包含一个必须要初始化的键值,表达式:
map[key]
返回默认的初始化 T,而 T 在上述例子中是 double 类型。默认的初始值为 0。至此,map 包含代理及其奖金汇总值对。下面的循环用来显示这些值对,输出如图一所示:
for(CIT p=bonuses.begin(); p!=bonuses.end(); ++p) { cout << p->first <<''\t'' << p->second <<endl; }