c++ map/multimap 主要包括:《map的介绍及接口的使用》《multimap的介绍及接口的使用》《map与multimap的区别》

如果想看set与multiset的使用,可以点下面的这个链接----》set/multiset的使用《----

《二》map
首先,我们学习map之前,和上面的set是一样的,我们要有查文档的习惯,下面,如果需要文档的,点这里——》》map文档的链接《《——

【1】map的介绍

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

【2】map的使用
2.1—map的参数说明
在这里插入图片描述
key: 键值对中key的类型
T: 键值对中value的类型
Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器
注意:在使用 map 时,需要包含 map 头文件。

【2.2】map的使用,这里文档里面说的很清楚了,所以我在这里就不多说什么了,我们还是看一下,一些有用的接口实现吧。
我们先看以下部分代码;
在这里插入图片描述
在这里插入图片描述
《 2.2.1 》 map的构造

首先,我们先看看一下,插入数据的实现代码。

void test_map1()
{
	std::map<int, int> m;
	m.insert(make_pair(1, 1));
	m.insert(make_pair(3, 3));
	m.insert(make_pair(2, 2));
	m.insert(make_pair(5, 5));
	m.insert(make_pair(4, 4));

	std::map<int, int>::iterator it = m.begin();
	while (it != m.end())
	{
		//cout << (*it).first << ":" << (*it).second << endl;
		cout << it->first << ":" << it->second << endl;
		++it;
	}
	cout << endl;
}

map的插入实现代码就是这些,我们在可以看一下上面的执行测试结果:
在这里插入图片描述
【2.2.2】map的可以统计数据的次数

//统计次数
void test_map2() 
{
	string s[] = { "苹果", "苹果", "苹果", "苹果", "橘子", "苹果", "苹果", "香蕉", "苹果", "香蕉", "苹果" };
	map<string, int> countmap;
	for (const auto& e : s)
	{
		//map<string, int>::iterator it = countmap.find(e);
		auto it = countmap.find(e);
		if (it != countmap.end())
		{
			it->second++;
		}
		else
		{
			countmap.insert(make_pair(e, 1));
		}
	}
	map<string, int>::iterator cit = countmap.begin();
	while (cit != countmap.end())
	{
		//cout << (*it).first << ":" << (*it).second << endl;
		cout << cit->first << ":" << cit->second << endl;
		++cit;
	}
}

下面,我们看一下代码执行的情况:
在这里插入图片描述
分析一下:先找到第一次出现的字符串,然后直接插入进去,当判断还不是 end 的时候,继续往下面走,如果是第一次出现的字符串,那么向第一次的基础上面加加,如果是新的字符串,那么直接在后面继续插入,这里就是统计次数的大致分析步骤。

【2.2.3】还是统计次数,但是不让你使用find,该怎么样实现呢?

下面,我们还是看一下,实现代码。

void test_map3() //统计次数
{
	string s[] = { "苹果", "苹果", "苹果", "苹果", "橘子", "苹果", "苹果", "香蕉", "苹果", "香蕉", "苹果" };
	map<string, int> countmap;
	for (const auto& e : s) //不让用find();
	{
		pair<std::map<string, int>::iterator, bool> ret = countmap.insert(make_pair(e, 1));
		//auto ret = countmap.insert(make_pair(e, 1));
		//auto缺陷,不容易读取,不知道里面什么内容
		if (ret.second == false)
		{
			ret.first->second++;
		}
	}
	map<string, int>::iterator cit = countmap.begin();
	while (cit != countmap.end())
	{
		//cout << (*it).first << ":" << (*it).second << endl;
		cout << cit->first << ":" << cit->second << endl;
		++cit;
	}
}

还是和上面一样,我在看一下执行程序:
在这里插入图片描述
总结分析:这里我们还是使用迭代器,但是不让我们使用 find(),我们可以选择使用 insert()接口,来实现统计次数,那是怎么样实现的呢?首先,再插入之前,我们看到程序,显示遍历了一遍,然后再插入新的字符串的时候,直接插入,后面,如果出现的是同一个字符串,那么就实现下面的代码,进行次数的加加爱,如果是新的字符串,那么就直接插入就可以了。

【2.2.4】还是统计次数,不让使用 find() ,并且不让使用迭代器,那么又该怎么实现呢?

下面,我们看一下代码。

void test_map4()
{
	string strs[] = { "苹果", "苹果", "西瓜", "苹果", "西瓜", "草莓", "草莓", "香蕉", "苹果", "苹果", "香蕉", "香蕉", "苹果", "苹果" };
	map<string, int> countmap;
	for (const auto& e : strs)
	{
		countmap[e]++;
	}

	for (const auto& e : countmap)
	{
		cout << e.first << ":" << e.second << endl;
	}
}

下面,我们来看一下实现代码的执行程序:
在这里插入图片描述
**总结分析:**先用范围for遍历一遍,排序,然后,将相同的字符串进行加起来,不同的,进行下一次的相加,直到整个字符串的结束,这样就实现了统计次数了,

通过上面的学习,我们可以实现部分map的 使用了,但是这些还不够,我还写了一些基础的小接口,我们可以在看一下

void test_map5()
{
	map<int, int> m;
	m.insert(make_pair(1, 1));
	m.insert(make_pair(3, 3));
	m.insert(make_pair(2, 2));
	m.insert(make_pair(5, 5));
	m.insert(make_pair(4, 4));
	m[1] = 1;
	//再某一个位置插入一个值
	m.insert(m.find(2), make_pair(6, 6));
	cout << m.size() << endl;
	//将这个程序遍历一遍,打印
	for (auto& e : m )
	{
		cout << e.first << "--->" << e.second << endl;
	}

	// map中的键值对key一定是唯一的,如果key存在将插入失败
	auto ret = m.insert(make_pair(7, 7));
	if (ret.second)
		cout << "<7, 7>不在map中, 已经插入" << endl;
	else
		cout << "键值为peach的元素已经存在:" << ret.first->first << "--->"
		<< ret.first->second << " 插入失败" << endl;
	//将上面的打印出来
	for (auto& e : m)
	{
		cout << e.first << "--->" << e.second << endl;
	}
	cout << "————————————"<<endl;
	//删除key为4的值
	m.erase(4);
	for (auto& e : m)
	{
		cout << e.first << "--->" << e.second << endl;
	}
	cout << "————————————" << endl;

	if (4 == m.count(4))
		cout << "4还在" << endl;
	else
		cout << "4不在了" << endl;
}

这里我已经把他的说明,在代码里面强调过了,所以,我这里就不用多说什么说明了,我们直接看执行程序结果。
在这里插入图片描述
最后一个截不上屏,但是,我相信,看代码一下就看懂了。这里就是我们实现的map的使用。
【总结】

  1. map中的的元素是键值对
  2. map中的key是唯一的,并且不能修改
  3. 默认按照小于的方式对key进行比较
  4. map中的元素如果用迭代器去遍历,可以得到一个有序的序列
  5. map的底层为平衡搜索树(红黑树),查找效率比较高O(log2 N)
  6. 支持[]操作符,operator[]中实际进行插入查找。

《二》multimap
首先. 和上面还是一样,还是可以用一下查文档的形式,首先,我先把文档的入口链接写在下面multimap的文档入口

【1】multimap的介绍

  1. Multimaps是关联式容器,它按照特定的顺序,存储由key和value映射成的键值对<key, value>,其中多个键值对之间的key是可以重复的。
  2. 在内部,multimap中的元素总是通过其内部比较对象按照指定的特定严格弱排序标准对key进行排序的。
  3. multimap通过key访问单个元素的速度通常比unordered_multimap容器慢,但是使用迭代器直接遍历multimap中的元素可以得到关于key有序的序列
  4. multimap在底层用二叉搜索树(红黑树)来实现

【2】multimap的部分接口实现

注意:
1. multimap中的key是可以重复的。
2. multimap中的元素默认将key按照小于来比较
3. multimap中没有重载operator[]操作(同学们可思考下为什么?)。
4. 使用时与map包含的头文件相同

【2.1】首先,我们先看一下,multimap的第一个特性,不去重,也有自己的用处。
下面,我们先看一下代码

void test_multimap6()
{
	multimap<string, string> m;
	m.insert(make_pair("李逵", "黑旋风"));
	m.insert(make_pair("林冲", "豹子头"));
	m.insert(make_pair("鲁达", "花和尚"));
	m.insert(make_pair("李逵", "铁牛"));

	cout << m.size() << endl;
	for (auto& e : m)
	{
		cout << "<" << e.first << "," << e.second << ">" << endl;
	}
	// key为李逵的元素有多少个
	cout << m.count("李逵") << endl;
}

下面,我们看一下执行结果;
在这里插入图片描述

这个接口是比较常用的,下面的接口就不太常用,但是,还是有一点用处的,所以,我就直接在代码区直接写了它的用途。

void test_multimap7()
{
	multimap<int, int> m;
	for (int i = 0; i < 10; ++i)
	{
		m.insert(pair<int, int>(i, i));
	}
	for (auto& e : m)
	{
		cout << e.first << "--->" << e.second << endl;
	}
	cout <<"——————————————"<< endl;
	// 返回m中大于等于5的第一个元素
	auto it = m.lower_bound(5);

	cout << it->first << "--->" << it->second << endl;
	// 返回m中大于5的元素

	it = m.upper_bound(5);
	cout << it->first << "--->" << it->second << endl;

}

在这里插入图片描述
当然,multimap,里面还有很多的接口,我就不实现了, 想要自己实现的同学们可以根据文档实现,自己的代码。

《三》set / map 区别

set O(logN)
1. 快速查找 key在不在?
2.排序+去重

map O(logN)
1.快速查找 通过key查找value;
2.附带作用,对key进行排序。通过字符串的大小进行排序的

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值