1. 简介
multimap是一种关联式容器,包含排序后的键值对,即 (key, value),允许相同的键值,内部会根据key值进行排序;增加、修改和查询具有对数的时间复杂度,其存储结构为红黑树;
头文件和定义
#include <map>
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T>>
> class multimap;
2. 初始化
初始化方式如下所示
#include <iostream>
#include <string>
#include <map>
template<typename T>
void showInfo(T &t)
{
auto iter = t.begin();
while (iter != t.end())
{
std::cout<<"["<<iter->first<<", "<<iter->second<<"]; ";
iter++;
}
std::cout<<std::endl;
}
int main()
{
//允许重复的数据出现,但是内部会对其进行排序
std::multimap<int32_t, std::string> mm1{
{
1,"c"},{
2,"linux"},{
1,"c++"},{
1,"c++"},{
2,"linux"}};
showInfo(mm1);
std::multimap<int32_t, std::string> mm2 = mm1;
showInfo(mm1);
std::multimap<int32_t, std::string> mm3;
mm3.emplace(std::make_pair(1, "teacher"));
mm3.emplace(std::make_pair(1, "student"));
mm3.insert({
3, "boy"});
mm3.emplace(std::pair<int32_t, std::string>(4, "girl"));
mm3.emplace_hint(mm3.begin(), std::make_pair(5, "class"));
showInfo(mm3);
return 0;
}
输出
[1, c]; [1, c++]; [1, c++]; [2, linux]; [2, linux];
[1, c]; [1, c++]; [1, c++]; [2, linux]; [2, linux];
[1, teacher]; [1, student]; [3, boy]; [4, girl]; [5, class];
3. 使用
其支持的操作与map大部分一样,但是有以下几点是不同的;
但是相比与set,像count()就有了用武之地;find()是查找第一个元素出现的时间;
- multimap不支持 at() 和 operator[],因为multimap中是允许数据重复的,不能通过下标来访问
- multimap不支持try_emplace(C++17)
既然multimap不支持下标访问,那么通过什么方式来访问元素呢?这个时候find()、count()、equal_range()、lower_bound() 和 upper_bound()就有了用武之地;
示例
int main()
{
std::multimap<int32_t, std::string> mm1{
{
1,"c"},{
2,"linux"},{
1,"c++"},{
1,"c++"},{
2,"linux"}, {
2,"python"},{
1,"matlab"}};
showInfo(mm1);
//1. 通过lower_bound和upper_bound输出元素相同的数据
std::cout<<"[1]\n";
auto lower_iter = mm1.lower_bound(1);
auto upper_iter = mm1.upper_bound(1);
decltype(lower_iter) m; //decltype自动推导出m的类型
for(m = lower_iter; m != upper_iter; m++)
{
std::cout<<"["<<m->first<<", "<<m->second<<"]; ";
}
std::cout<<std::endl<<std::endl;
//2. 通过equal_range来查找元素
std::cout<<"[2]\n";
auto equal_iter = mm1.equal_range(1);
auto lower_iter_1 = equal_iter.first;
auto upper_iter_2 = equal_iter.second;
decltype(lower_iter_1) m_1;
for(m_1 = lower_iter_1; m_1 != upper_iter_2; m_1++)
{
std::cout<<"["<<m_1->first<<", "<<m_1->second<<"]; ";
}
std::cout<<std::endl<<std::endl;
//3. find() 和 count()
std::cout<<"[3 ]\n";
auto iter = mm1.find(1);
if(iter != mm1.end())
{
for(size_t i = 0;i <mm1.count(1);i++)
{
std::cout<<"["<<iter->first<<", "<<iter->second<<"]; ";
iter++;
}
}
std::cout<<std::endl;
return 0;
}
输出
[1, c]; [1, c++]; [1, c++]; [1, matlab]; [2, linux]; [2, linux]; [2, python];
[1]
[1, c]; [1, c++]; [1, c++]; [1, matlab];
[2]
[1, c]; [1, c++]; [1, c++]; [1, matlab];
[3]
[1, c]; [1, c++]; [1, c++]; [1, matlab];