map与multimap
目录
map
map的介绍
map的使用
map的模版参数
map的构造
map的迭代器
map的容量
map中元素的修改
map中的查找
map的元素访问
multimap
map
map的介绍
- map是关联式容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素
- 在map中,键值key通常用于排序和唯一的标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,且在map内部,key和value通过成员类型value_type绑定在一起, 为其取名为pair:typedef pair<const key,value> value_type
- 在map中,元素总是根据key值进行比较排序
- map中通过key访问单个元素的速度通常比unordered_map容器要慢,但map允许根据顺序对元素进行直接迭代
- map支持下标访问符,即在[]中放入key,就可以找到与其相对应的value
- map的底层是二叉搜索数
map的使用
map的模版参数
map的构造
map的迭代器
map的容量
map中元素的修改
insert:
这里我们重点看(1),首先(1)插入的元素看似是一个值,但它却是一个类类型,因为value_type是它的重命名,其真正的类型是pair<const key_type,mapped_type>,因此我们想要插入一个元素就要将其转化为pair类型
其次(1)的返回值,我们可以看到该返回值是一个类,且该类将两个不同类型的变量组合成了一个单元,在这里第一个变量存储了插入元素的迭代器,第二个变量存储的是一个bool值。如果插入成功,那么迭代器指向插入的那个元素,且bool值为true;如果插入失败(map中存在该值),则迭代器指向与插入值相等的那个元素的位置,bool值为false。
在这里我们可以看一下pair的模版参数:
里面有两个成员变量分别命名为first和second,如图:
其构造函数如图:
代码如下:
void test_pair()
{pair<string, int> s1;pair<string, int> s2("苹果", 1);pair<string, int> s3(s2);s1 = make_pair("香蕉", 2);cout << s1.first << ":" << s1.second << endl;cout << s2.first << ":" << s2.second << endl;cout << s3.first << ":" << s3.second << endl;
}
运行结果如图:
从上面我们可以看到pair的构造有两种,第一种是直接构造,第二中是通过make_pair函数进行构造
make_pair函数的模版参数如下:
其作用是构造一个pair对象,其第一个元素设置为x,第二个元素设为y,分别对应pair的first和second
因此,map中插入一个元素的代码如下所示:
void test_map1()
{map<string, int> mst;mst.insert(pair<string, int>("苹果", 1));mst.insert(make_pair("香蕉", 2));mst.insert(make_pair("橙子", 3));mst.insert(make_pair("橘子", 4));for (auto& mit : mst){cout << mit.first << ":" << mit.second << endl;}
}
注:insert的返回值是一个pair,因此要用pair接收
erase
(1)删除迭代器位置上的元素
(2)删除等于k的元素,并返回删除的个数
(3)删除一段迭代器区间
map中的查找
我们可以看到find的参数类型是key_type,这说明map的查找是通过key进行的,与value无关
map的元素访问
我们可以看到该函数的参数为key,返回值是value的引用,因此我们可以通过该函数对value修改。
C++库中,调用该函数相当于调用了下面这段代码:
(*((this->insert(make_pair(k,mapped_type()))).first)).second
对上面这段代码进行解释,首先调用这段语句通过make_pair函数创建了一个pair对象,其中first是要插k,second则是根据默认构造函数创建的值;其次调用这段语句
在这个map中插入该pair对象,并返回一个pair对象,该pair对象中存储的是该元素位置的迭代器和一个bool值;最后就是对该插入元素位置的迭代器解引用,解引用得到插入的那个pair对象,并取这个pair对象的second进行返回,由于返回是引用返回,因此可以通过该函数对value进行修改
void test_map2()
{map<string, int> mst;string s[] = {"香蕉","苹果","橘子","橙子","香蕉" ,"香蕉" ,"橘子" ,"椰子"};for (auto& sit : s){mst[sit]++;//首先从map里面找与sit相同的元素,如果没有就插入该元素并初始化value,如果有就找到该元素并对该元素的value值++}for (auto& mit : mst){cout << mit.first << ":" << mit.second << endl;}
}
总结
- map中的元素是键值对
- map中的key是唯一的,并且不能修改
- 默认按照小于的方式对key进行比较
- map中的元素如果用迭代器取遍历会得到一个有序序列
- map的底层是一个平衡搜索树,查找效率为
- 支持[]操作符,operator[]中实际进行插入查找
multimap
multimap和map基本类似,它们的唯一区别就是map中的key是唯一的,而multimap中的key是可以重复的
multimap的接口可以参考map,功能都类似。其中insert会插入一个新的pair<key,value>不会取改变里面与key相同的value值
注:multimap中没有重载operator[]操作,这是因为key可以重复,operator[]不知道该去调用哪个key