C++set和map详细介绍-四.map

map就是对应我们二叉树中的KV模型

1.map文档介绍

在这里插入图片描述
看一下模板参数
在这里插入图片描述
包括四个值:
????Key:键值对中的key值
????T:键值对中的value值
????Compare:比较器类型,一般是按照小于比较。如果是自定义类型,需要自己传递这个比较方式,达到要求。
????Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的
空间配置器

set文档介绍

  1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素。
  2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair:
    typedef pair<const key, T> value_type;
  3. 在内部,map中的元素总是按照键值key进行比较排序的。
  4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
  5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。
  6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))

看一下要点:
????????map中存储的是一个键值对,键值对中第一个元素,也就是key,根据key值进行排序,确定唯一元素。
第二个值value,与key的内容关联。
????????元素不可以修改key的值,但是可以修改value的值。
????????支持下标访问,把key放在[ ]中,可以找到与之对应的value元素。

2.map成员函数

这其中与很多和set的成员函数相同,在这里我就不再重复阐述了。
接下来主要讲述一些不同点,以及重点内容。
在这里插入图片描述

1.构造

????????1.有名构造
    pair<string, string>p = { “pear”, “梨” };
    m.insert( p);
????????2.匿名构造
   m.insert(pair<string, string>(“apple”, “苹果”));
????????3.make_pair
    m.insert(make_pair(“banana”, “香蕉”));
在这里插入图片描述
c++98新增的,本质就是一个函数模板

????????4.c++11多参数隐式类型转换
    m.insert({“strawberrier” ,“草莓”});

2.insert插入

我们看一下官方文档
在这里插入图片描述
我们主要看一下第一条:

插入的是一个pair类型,返回值也是一个pair类型

我们来看一下有关返回值的介绍
在这里插入图片描述

如果插入到元素存在,返回值中的iterator就指向这个存在的位置的迭代器,bool值为false
如果插入元素不存在,返回值中的iterator就指向这个新插入的位置的迭代器,bool值为true
这里的元素插入是看key的值,与value无关。

3.count

在这里插入图片描述
count返回key为x的键值在map中的个数,注意map中key是唯一的,因此该函数的返回值要么为0,要么为1,因此也可以用该函数来检测一个key是否在map中。

4.迭代器

我们注意一下map有两个值,我们再遍历的时候,不能只遍历一个,要把两个分开。


	for (auto& kv : m)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
	cout << endl;

first代表pair第一个值,second代表pair第二个值。

5.【】和at

map中支持【】访问元素。

如果我们想要统计水果出现的次数
第一步:先看这个水果在不在!!
第二步:如果不在,就把这一个键值对插入进去。如果在,就让vaule这个值加加。
最后遍历一边元素,就完成了

我们再map中不用折磨麻烦,我们看一下这个巧妙的代码。

// 统计水果出现的次数
string arr[] = { "苹果", "西瓜", "苹果", "西瓜", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
map<string, int> m;
for (auto& e : arr)
{
	m[e]++;
}

m[e]++;就完成了操作。

我们来看一下怎末实现的??
在这里插入图片描述
【】的返回值是value类型,参数是一个key类型。

在文档中还有这样一段话,我们来剖析一下。
在这里插入图片描述
在这里插入图片描述

这个【】需要调用insert,insert上面我们已经介绍过了,拆分来看一下
????insert(make_pair(k,mapped_type()))这个是insert的原型,插入一个键值对,key值必须传入,如果value不传入,采用缺省值。
这个k存在,就返回这个k这个值的迭代器,不存在,就返回新插入这个k的迭代器。
????this->insert(make_pair(k,mapped_type()))调用这个返回值pair
????(this->insert(make_pair(k,mapped_type()))).first调用这个返回值的pair的第一个元素iterator,迭代器本身就是指针。
????(*((this->insert(make_pair(k,mapped_type()))).first)).second
这个迭代器指向的第二个元素,就是value.

通过这种方式我们就拿到了value的值
如果不存在,插入成功,返回新插入元素的迭代器
如果已存在,插入失败,返回该key所在位置的迭代器
operator[]函数最后将insert返回值键值对中的value返回

在元素访问时,有一个与operator[]类似的操作at()(该函数不常用)函数,都是通过key找到与key对应的value然后返回其引用
不同的是:当key不存在时,operator[]用默认value与key构造键值对然后插入,返回该默认value,at()函数直接抛异常。

我们看一下这段代码的结果是什么??

	map<string, string> dict;
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("string", "字符串"));
	dict.insert(make_pair("sort", "xxx"));

在这里插入图片描述

只与key的值有关,与value无关。
key相同,value不同,不会插入也不会更新

这个【】就有很多功能了,也可以插入,也可以查找,也可以修改
在这里插入图片描述

上一篇:docker0: iptables: No chain/target/match by that name


下一篇:Linux之shell脚本编辑工具awk