目录
一、set
二、map
1.插入
2.隆重介绍 []
A使用场景
B原理
一、set
set即STL库中提供的K模型的二叉搜索树,他的函数使用和其他容器很相似,可以自行阅读文档#include <set>
本文旨对库中难以理解的函数作说明
二、map
map即KV模型的二叉搜索树
1.插入
第一种写法:
map<string, string> dict;
//insert
dict.insert(pair<string, string>("english", "英语"));
插入说明:
关于value_type是什么
即KV模型的K被typedef为key_type,V被typedef为mapped_type,而一对数据KV用一个叫做pair的类模板进行封装,再typedef为 value_type。
pair的定义在头文件<utility>中,该头文件的含义是有各种用途的
那么第一种写法中的实参其实为匿名对象的写法。或者
//c++11支持多参数的构造函数的隐式类型转换
dict.insert({ "superman","超人" });
<utility>中包含一个函数make_pair,返回一个pair
因此,上述代码还可以这样写:
//make_pair dict.insert(make_pair("english", "英语"));
2.隆重介绍 []
A使用场景
要求统计个数。比如要求你统计数组中有每种水果有几个
string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜",
"苹果", "香蕉", "苹果", "西瓜", "香蕉", "草莓" };
map<string, int> countMap;
for (auto& e : arr)
{
map<string, int>::iterator it = countMap.find(e);
if (it != countMap.end())
{
it->second++;
}
else
{
countMap.insert(make_pair(e, 1));
}
}
for (auto& kv : countMap)
{
cout << kv.first << ":" << kv.second << endl;
}
cout << endl;
这是正常的写法。但是如果对重载的[]的作用理解深刻,还可以这样写:
map<string, int> countMap;
for (auto& e : arr)
{
countMap[e]++;
}
for (auto& kv : countMap)
{
cout << kv.first << ":" << kv.second << endl;
}
cout << endl;
运行结果都是一样的:
B原理
在该函数的说明文字中,有这样一句话:
将.first之前的内容截取出来
再来看看insert的返回值
足以说明,此处是一个pair类型的对象, .first说明访问第一个参数iterator,.second说明访问valut_type的第二个参数,代入到这个例子中,就是int类型的变量,即个数。
可以大致的理解为:
mapped_type& operator[](const key_type& k) { pair<iterator, bool> ret = insert(make_pair(key, V())); return ret.first->second; }
而insert对返回值的说明是,如果key存在,则返回pair中的first为以及存在在位置,bool为false表示插入失败;如果key不存在,则返回pair中的first为插入后的位置,bool为true
利用这一点:
for (auto& e : arr)
{
pair<map<string, int>::iterator, bool> ret;
ret = countMap.insert(make_pair(e, 0));
ret.first->second++;
}
等效为
for (auto& e : arr)
{
countMap[e]++;
}