认识map
map类型通常被称为关联数组,关联数组与“正常”数组类似,不同之处在于其下标不必是整数。
①map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对。它提供基于key的快速检索能力。
②map中key值是唯一的。集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。
③map的具体实现采用红黑树变体的平衡二叉树的数据结构。在插入操作和删除操作上比vector快。
④map可以直接存取key所对应的value,支持[]操作符,如map[key]=value。
⑤multimap与map的区别:map支持唯一键值,每个键只能出现一次;而multimap中相同键可以出现多次。multimap不支持[]操作符。
经典案例:单词计数程序
从键盘获取一系列单词,统计每个单词出现的次数
#include <iostream>
#include <map>
#include <cstdlib>
#include <string>
using namespace std;
int main()
{
map<string, int> word_count;
string word;
while(cin >> word)
{
//这里是关键,用下标法访问map,存在两种情况:
//①map容器中不存在输入的关键字,此时会创建一个该关键字的元素到map容器中,而对应该关键字的值默认为0
//②map容器中存在输入的关键字,此时下标操作即访问容器中的该元素
//下面这条语句同时解决了两种情况
++word_count[word];
}
//写法1
//for(map<string, int>::const_iterator it = word_count.begin(); it != word_count.end(); it++)
//{
// cout << it->first << " occurs " << it->second << " " << ((it->second > 1) ? "times" : "time") << endl;
//}
//写法2
for(map<string, int>::const_iterator it = word_count.begin(); it != word_count.end(); it++)
{
//(*it).first 等价于 it->first,*it 代表解引用it
//当从map中获取一个元素时,会得到一个pair类型的对象
//pair是一个模板类型,保存名为first和second的公有数据成员
//这里first成员保存对应map的关键字(key),second成员保存对应map的值(value)
//啰嗦一句。这里为什么要解引用?因为it只是一个迭代器对象,它没有first和second成员;而“->”可以这样是因为“->”操作符已经包含了解引用
//这也是一个对象指针可以使用->访问对象成员的原因
cout << (*it).first << " occurs " << (*it).second << " " << (((*it).second > 1) ? "times" : "time") << endl;
}
//写法3,采用C++11新标准语法,前提是你的编译器支持该语法
//for(const auto &w : word_count)
//{
// cout << w.first << " occurs " << w.second << " " << ((w.second > 1) ? "times" : "time") << endl;
//}
//此句作用相当于阻塞控制台窗口
//system就是从程序中调用系统命令,该命令存在头文件stdlib.h中,可添加头文件cstdlib
system("pause");
return 0;
}
运行程序
键入单词以enter键进行分割,最后按Ctrl+Z结束输入。
注意输出时的单词顺序,其实map默认是按升序排序,如果想要变为降序排列,改为以下方式:
map<string, int, greater<string> >