map
1. map的介绍
翻译:
- map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
- 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair: typedef pair<const key, T> value_type;
- 在内部,map中的元素总是按照键值key进行比较排序的。
- map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
- map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
- map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。
2. map的使用
map的模板参数说明 :
key: 键值对中key的类型
T: 键值对中value的类型
Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器
注意:在使用map时,需要包含头文件
2.1 insert
insert参数文档:
使用示例:
#include <iostream>
using namespace std;
#include <map>
void test_map()
{
map<string, string> dict;
dict.insert(pair<string, string>("sort","排序"));
dict.insert(pair<string, string>("insert", "排序"));
dict.insert(pair<const char *, const char *>("left", "左边"));
dict.insert(make_pair("right", "右边")); //推荐这个写法
string s1("pzh"), s2("solity");
dict.insert(make_pair(s1, s2));
map<string, string>::iterator it = dict.begin();
while(it != dict.end())
{
cout << (*it).first << ":" << (*it).second << endl;
++it;
}
}
int main()
{
test_map();
return 0;
}
示例结果:
这里需要注意,first不能修改,然而second可以修改:
for(auto& e : dict)
{
e.first += 'x';
e.second += 'x';
}
2.2 统计次数操作
#include <iostream>
using namespace std;
#include <map>
void test_map()
{
string arr[] = {"apple", "banana", "apple", "pear", "apple", "banana", "apple", "banana"};
map<string, int> countmap;
for(auto& str : arr)
{
auto ret = countmap.find(str);
if(ret == countmap.end())
{
//没有表示第一次出现,插入
countmap.insert(make_pair(str, 1));
}
else
{
//次数++
ret->second++;
}
}
for (auto &e : countmap)
{
cout << e.first << ":" << e.second << endl;
}
}
int main()
{
test_map();
return 0;
}
显示结果:
当然你也有更简洁的方法:
#include <iostream>
using namespace std;
#include <map>
void test_map()
{
string arr[] = {"apple", "banana", "apple", "pear", "apple", "banana", "apple", "banana"};
map<string, int> countmap;
for(auto& str : arr)
{
countmap[str]++;
}
for (auto &e : countmap)
{
cout << e.first << ":" << e.second << endl;
}
}
int main()
{
test_map();
return 0;
}
结果依然正确:
2.3 operator[ ]
官方文中的operator[ ]参数模板:
理解这个之前还要关注一下文档中insert的返回值:
从官方介绍来看:
- 插入成功 pair<新插入的key所在节点的iterator,true>
- 插入失败 pair<已经存在的key所在节点的iterator,false>
这也就是解释了上述2.2示例中简洁方法的原理!!!
当然还有插入修改功能:
#include <iostream>
using namespace std;
#include <map>
void test_map()
{
map<string, string> dict;
dict.insert(pair<string, string>("sort", "排序"));
dict.insert(pair<string, string>("insert", "排序"));
dict.insert(pair<const char *, const char *>("left", "左边"));
dict.insert(make_pair("right", "右边"));
dict["erase"]; //插入
cout << dict["erase"] << endl; //查找
dict["erase"] = "删除"; //修改
cout << dict["erase"] << endl; //查找
dict["test"] = "测试"; // 插入+修改
dict["test"] = "测试"; //修改
}
int main()
{
test_map();
return 0;
}
可以通过调试逐步观察dict对象中内容的变化!!!
2.4 其余操作
用法与set操作基本相同!!!!