目录
1、map的简述
map与set一样是关联式容器
map就相当于二叉搜索树中的KV模型,底层是使用红黑树实现的,仿函数默认是less,即比根小的往左走,比根大的往右走。但是,map中的Key和Value是组合在一起的,是一个新的数据结构pair。pair称为键值对。map中也是不能键值冗余的
2、map的使用
map大部分是和set相似的,这里就介绍几个与set有较大区别的成员函数
2.1 insert
在pair中,两个成员变量称为first和second。注意:map中结点的first是const的,一旦放入,不允许修改
template <class T1, class T2>
struct pair
{
typedef T1 first_type;
typedef T2 second_type;
T1 first;
T2 second;
pair(): first(T1()), second(T2())
{}
pair(const T1& a, const T2& b): first(a), second(b)
{}
};
所以,向map中插入元素时,不能将两个值分开写,应该将两个值放入一个pair才能放入
void test_map1()
{
map<string, string> dict;
dict.insert("left", "左边");
}
像上面这样的写法就是错的,下面介绍4种写法
pair中有一个make_pair函数是用来创建一个pair对象的
void test_map1()
{
map<string, string> dict;
// 1、定义有名对象
pair<string, string> kv1("left", "左边");
dict.insert(kv1);
// 2、定义匿名对象
dict.insert(pair<string, string>("right", "右边"));
// 3、用make_pair创建一个对象
dict.insert(make_pair("insert", "插入"));
// 4、用花括号括起来,多参数的隐式类型转换
dict.insert({ "string","插入" });
}
map初始化是可以使用迭代器区间初始化的
void test_map2()
{
map<string, string> dict = { {"left","右边"},{"right","右边"},{"insert","插入"} };
}
外层的{}是initializer_list,内层的{}是隐式类型转换
2.2 operator*、operator->
pair是不支持流插入和流提取的,所以想要获得map的迭代器中的值不能直接对迭代器解引用
void test_map2()
{
map<string, string> dict = { {"left","右边"},{"right","右边"},{"insert","插入"} };
map<string, string>::iterator it = dict.begin();
while (it != dict.end())
{
cout << (*it) << " ";
++it;
}
}
此时cout处是会报错的,因为*it获得的是pair对象,而pair对象又不支持流提取和流插入
void test_map2()
{
map<string, string> dict = { {"left","右边"},{"right","右边"},{"insert","插入"} };
map<string, string>::iterator it = dict.begin();
while (it != dict.end())
{
cout << (*it).first << "-" << (*it).second << endl;
++it;
}
}
因为pair里面存的数据类型支持流插入和流提取,结果是,遍历出的顺序与插入顺序是不同的,因为是按Key,即pair的first进行了排序
不过,最方便的其实是使用->来访问pair中的数据
void test_map2()
{
map<string, string> dict = { {"left","右边"},{"right","右边"},{"insert","插入"} };
map<string, string>::iterator it = dict.begin();
while (it != dict.end())
{
cout << it->first << "-" << it->second << endl;
++it;
}
}
这里是省略了一个->的,前面也有讲过
迭代器的operator*是返回里面数据的引用,迭代器的operator->是返回里面数据的指针。其实当容器的数据存的是一个结构体时,若要访问迭代器里面的数据,是没办法*it的,需要(*it).xxx,此时更推荐使用opertaor->
可以使用迭代器则一定可以使用范围for
void test_map3()
{
map<string, string> dict = { {"left","右边"},{"right","右边"},{"insert","插入"} };
map<string, string>::iterator it = dict.begin();
for (const auto& e : dict)
{
cout << e.first << "-" << e.second << endl;
}
for (auto& [x, y] : dict)
{
cout << x <&l