C++ STL 之关联容器 map 详解

Part.I Attention

在这里插入图片描述
C++ 中 map 提供的是一种键值对容器,里面的数据都是成对出现的,每一对中的第一个值称之为关键字(key),每个关键字只能在 map 中出现一次;第二个称之为该关键字的对应值(Value)。

Chap.I 注意事项

使用map需要注意的地方:

  • 加引用#include <map>
  • 头文件map中除了有map,还有multimap;另外头文件unordered_map中也有相似的容器unordered_map, unordered_multimap,它们之间的区别如下:
名称 含义
map 在map中,键值key通常用于唯一的标识元素,而值value中存储与此键值key关联的内容;键值key和value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名为pair;map中的key是唯一的,并且不能修改,遇到重复的key就会插入失败;但可以利用operator[]对value进行修改;map的底层实现为红黑树,查找效率比较高,是O(logN);
multimap 与map的区别在于:multimap中的key可以重复;multimap中没有重载operator[]功能;对于重复的元素,查找的时候也是返回中序遍历的第一个元素。
unordered_map 存储键值对 <key, value> 类型的元素,其中各个键值对键的值不允许重复,且该容器中存储的键值对是无序的。
unordered_multimap 和 unordered_map 唯一的区别在于,该容器允许存储多个键相同的键值对。
  • 最基本的构造函数示例:std::map<int, std::string> mapPerson;
  • map中的元素是按照一定顺序存储的,默认是按键(key)升序排列的;
map<T1, T2> m;	//默认按键的升序方式排列元素,相当于 map<T1, T2, less<T1>> m
map<T1, T2, less<T1>> m; //该容器是按键的升序方式排列元素。
map<T1, T2, greater<T1>> m;  //该容器是按键的降序方式排列元素。

Chap.II 操作技巧

下面是一些操作示例:

// 用insert函數插入pair
mapStudent.insert(make_pair(000, "student_zero"));
// 用insert函數插入pair
mapStudent.insert({
    
    000, "student_zero"});
// 用insert函數插入pair
mapStudent.insert(pair<int, string>(000, "student_zero"));
// 用"array"方式插入
mapStudent[123] = "student_first";
// 查找元素,没找到就返回 end
mapStudent.find("123")!=mapStudent.end()
// 根据键值删除元素,如果删除成功返回1,否则返回0
mapStudent.erase("123");
// 清空整个 map
mapStudent.erase(mapStudent.begin(), mapStudent.end());

Part.II Funciton

这里仅仅介绍map的函数(其他三种map的函数和它大差不差,有些少一些函数或者多那么几个函数),如下图:

在这里插入图片描述

函数 含义
begin() 返回指向 map 头部的迭代器(注意是排好序的)
clear() 删除所有元素
count(key) 返回键key出现的次数,map中此函数返回的最大值为1
empty() 如果 map 为空则返回 true
emplace() 在当前 map 容器中的指定位置处构造新键值对。其效果和插入键值对一样,但效率更高。
end() 返回指向 map 末尾的迭代器,注意它可不是最后一个元素,而是容器的末尾,类似于char[]类型中的'\0'
equal_range() 该方法返回一个 pair 对象(包含 2 个双向迭代器),其中 pair.firstlower_bound() 方法的返回值等价,pair.secondupper_bound() 方法的返回值等价。也就是说,该方法将返回一个范围,该范围中包含的键为 key 的键值对(map 容器键值对唯一,因此该范围最多包含一个键值对)。
erase() 删除 map 容器指定位置、指定键(key)值或者指定区域内的键值对。
find(key) 在 map 容器中查找键为 key 的键值对,如果成功找到,则返回指向该键值对的双向迭代器;反之,则返回和 end() 方法一样的迭代器。
get_allocator() 返回map的配置器,比如map<string, int>::allocator_type
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound(key) 返回一个指向当前 map 容器中第一个大于或等于 key 的键值对的双向迭代器
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound(key) 返回一个指向当前 map 容器中第一个大于 key 的键值对的迭代器。
value_comp() 返回比较元素 value 的函数

Part.III Code

Chap.I map

测试代码如下:

#include <iostream>
#include <iomanip>
#include <map>

using namespace std;

int main()
{
    
    
    map<string,int> data {
    
    {
    
    "Tom",10},{
    
    "Jerry",20}};
    // map<string,int> data {make_pair("Tom",10),make_pair("Jerry",20)}    // the same as above
    auto tmp=data.begin();
    cout<< tmp->first << " " << tmp->second<<endl;
    data["Allice"]=30;
    data.insert({
    
    "Tony",10});
    cout<<data["Tony"] << endl;
    data.insert({
    
    "Tony",20}); // it can't work, data["Tony"]=20; is OK!
    cout<<data["Tony"] << endl;
    tmp=data.begin();
    cout<< tmp->first << " " << tmp->second<<endl;
    cout<<data.size() << setw(15)<<data.max_size()<<endl;
    for(auto itr=data.rbegin();itr!=data.rend();itr++)
        cout<< itr->first<<" " <<itr->second<< endl;
    getchar();
    return 0;
}

输出如下:

Jerry 20
10
10
Allice 30
4       97612893
Tony 10
Tom 10
Jerry 20
Allice 30

Chap.II unordered_map

测试代码如下:

#include <iostream>
#include <iomanip>
#include <unordered_map>

using namespace std;

int main()
{
    
    
    unordered_map<string,int> data {
    
    {
    
    "Tom",10},{
    
    "Jerry",20}};
    // map<string,int> data {make_pair("Tom",10),make_pair("Jerry",20)}    // the same as above
    auto tmp=data.begin();
    cout<< tmp->first << " " << tmp->second<<endl;
    data["Allice"]=30;
    data.insert({
    
    "Tony",10});
    cout<<data["Tony"] << endl;
    data.insert({
    
    "Tony",20}); // it can't work, data["Tony"]=20; is OK!
    cout<<data["Tony"] << endl;
    tmp=data.begin();
    cout<< tmp->first << " " << tmp->second<<endl;
    cout<<data.size() << setw(15)<<data.max_size()<<endl;
    for(auto itr=data.begin();itr!=data.end();itr++)
        cout<< itr->first<<" " <<itr->second<< endl;
    getchar();
    return 0;
}

输出如下:

Jerry 20
10
10
Tony 10
4      119304647
Tony 10
Allice 30
Jerry 20
Tom 10

Chap.III multimap

测试代码如下:

#include <iostream>
#include <iomanip>
#include <map>

using namespace std;

int main()
{
    
    
    multimap<string,int> data {
    
    {
    
    "Tom",10},{
    
    "Jerry",20}};
    // map<string,int> data {make_pair("Tom",10),make_pair("Jerry",20)}    // the same as above
    auto tmp=data.begin();
    cout<< tmp->first << " " << tmp->second<<endl;
    data.insert({
    
    "Allice",30});
    data.insert({
    
    "Tony",10});
    auto ret=data.equal_range("Tony");
    for(auto itr=ret.first;itr!=ret.second;itr++)
        cout<<itr->second<< " ";
    cout << endl;
    data.insert({
    
    "Tony",20}); // it work! data["Tony"]=20; is Error!
    ret=data.equal_range("Tony");
    for(auto itr=ret.first;itr!=ret.second;itr++)
        cout<<itr->second<< " ";
    cout << endl;
    tmp=data.begin();
    cout<< tmp->first << " " << tmp->second<<endl;
    cout<<data.size() << setw(15)<<data.max_size()<<endl;
    for(auto itr=data.begin();itr!=data.end();itr++)
        cout<< itr->first<<" " <<itr->second<< endl;
    getchar();
    return 0;
}

输出如下:

Jerry 20
10
10 20
Allice 30
5       97612893
Allice 30
Jerry 20
Tom 10
Tony 10
Tony 20

猜你喜欢

转载自blog.csdn.net/Gou_Hailong/article/details/128389898