如果想看set与multiset的使用,可以点下面的这个链接----》set/multiset的使用《----
《二》map
首先,我们学习map之前,和上面的set是一样的,我们要有查文档的习惯,下面,如果需要文档的,点这里——》》map文档的链接《《——
【1】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 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::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 countmap;
for (const auto& e : s)
{
//map::iterator it = countmap.find(e);
auto it = countmap.find(e);
if (it != countmap.end())
{
it->second++;
}
else
{
countmap.insert(make_pair(e, 1));
}
}
map::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 countmap;
for (const auto& e : s) //不让用find();
{
pair::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::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 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 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 << "————————————"<" << e.second << endl;
}
cout << "————————————" << endl;
if (4 == m.count(4))
cout << "4还在" << endl;
else
cout << "4不在了" << endl;
}
这里我已经把他的说明,在代码里面强调过了,所以,我这里就不用多说什么说明了,我们直接看执行程序结果。
最后一个截不上屏,但是,我相信,看代码一下就看懂了。这里就是我们实现的map的使用。
【总结】
《二》multimap
首先. 和上面还是一样,还是可以用一下查文档的形式,首先,我先把文档的入口链接写在下面multimap的文档入口
【1】multimap的介绍
【2】multimap的部分接口实现
注意:
1. multimap中的key是可以重复的。
2. multimap中的元素默认将key按照小于来比较
3. multimap中没有重载operator[]操作(同学们可思考下为什么?)。
4. 使用时与map包含的头文件相同:
【2.1】首先,我们先看一下,multimap的第一个特性,不去重,也有自己的用处。
下面,我们先看一下代码
void test_multimap6()
{
multimap 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 m;
for (int i = 0; i < 10; ++i)
{
m.insert(pair(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进行排序。通过字符串的大小进行排序的