• [C++ STL] map使用详解


    一、概述

    map 由红黑树实现,其元素都是 “键值/实值” 所形成的一个对组(key/value pairs)。每个元素有一个键,是排序准则的基础。每一个键只能出现一次,不允许重复。

    map主要用于资料一对一映射的情况,map 内部自建一颗红黑树,这颗树具有对数据自动排序的功能,所以在 map 内部所有的数据都是有序的。比如一个班级中,每个学生的学号跟他的姓名就存在着一对一映射的关系。


    二、定义及初始化

    使用之前必须加相应容器的头文件:

    #include <map> // map属于std命名域的,因此需要通过命名限定,例如using std::map;
    

    定义的代码如下:

    map<int, string> a; // 定义一个int类型的映射a
    // map<int, string> a(10); // error,未定义这种构造函数
    // map<int, string> a(10, 1); // error,未定义这种构造函数
    map<int, string> b(a); // 定义并用映射a初始化映射b
    // map<int, string> b(a.begin(), a.end());  // error,未定义这种构造函数
    

    三、基本操作

    3.1 容量函数

    • 容器大小:mp.size();
    • 容器最大容量:mp.max_size();
    • 容器判空:mp.empty();
    • 查找键 key 的元素个数:mp.count(key);
    #include <iostream>
    #include <map>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	map<int,string> mp;
    	mp.insert({ 1, "张三" });
    	mp.insert({ 2, "李四" });
    	mp.insert(pair<int, string>{ 3, "隔壁老王" });
    
    	cout << mp.size() << endl; // 输出:3
    	cout << mp.max_size() << endl; // 输出:89478485 // 输出:1
    	cout << mp.count(2) << endl; // 输出:1
    	if (mp.empty())
    		cout << "元素为空" << endl; // 未执行
    
    	return 0;
    }
    

    3.2 添加函数

    • 在容器中插入元素:mp.insert(const T& x);
    • 任意位置插入一个元素:mp.insert(iterator it, const T& x);
    #include <iostream>
    #include <map>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	map<int,string> mp;
    	// 在容器中插入元素
    	mp.insert({ 1, "张三" });
    	mp.insert({ 2, "李四" });
    	// 任意位置插入一个元素
    	map<int, string>::iterator it = mp.begin();
    	mp.insert(it, pair<int, string>{ 3, "隔壁老王" }); // 会自动排序
    
    	for (it = mp.begin(); it != mp.end(); it++)
    		cout << it->first << " " << it->second << endl;
    	cout << endl;
    
    	return 0;
    }
    
    /*
    1 张三
    2 李四
    3 隔壁老王
    */
    

    3.3 删除函数

    • 删除键值为 keyValue 的元素:mp.pop_back(const T& keyValue);
    • 删除迭代器所指的元素:mp.erase(iterator it);
    • 删除区间[first,last]之间的所有元素:mp.erase(iterator first, iterator last);
    • 清空所有元素:mp.clear();
    #include <iostream>
    #include <map>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	map<int,string> mp;
    	// 在容器中插入元素
    	mp.insert({ 1, "张三" });
    	mp.insert({ 2, "李四" });
    	mp.insert({ 4, "王五" });
    	mp.insert({ 5, "小明" });
    	// 任意位置插入一个元素
    	mp.insert(mp.begin(), pair<int, string>{ 3, "隔壁老王" }); // 会自动排序
    
    	// 删除键值为keyValue的元素
    	mp.erase(2);
    	// 删除迭代器所指的元素
    	mp.erase(mp.begin());
    	// 删除区间[first,last]之间的所有元素
    	mp.erase(mp.begin(), ++mp.begin());
    
    	// 遍历显示
    	map<int, string>::iterator it = mp.begin();
    	for (it = mp.begin(); it != mp.end(); it++)
    		cout << it->first << " " << it->second << endl;
    
    	// 清空容器内的所有元素
    	mp.clear();
    
    	// 判断map是否为空
        if (st.empty())
            cout << "元素为空" << endl; // 输出:元素为空
    
    	return 0;
    }
    
    /*
    4 王五
    5 小明
    元素为空
    */
    

    3.4 访问函数

    • 查找键 key 是否存在,若存在,返回该键的元素的迭代器;若不存在,返回 map.end(): mp.find(key);
    #include <iostream>
    #include <map>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	map<int,string> mp;
    	// 在容器中插入元素
    	mp[1] = "张三";
    	mp[2] = "李四";
    	mp[3] = "隔壁老王";
    
    	// 通过find(key)查找键值
    	cout << mp.find(1)->first << endl; // 输出:1
    	cout << mp.find(2)->second << endl; // 输出:李四
    
    	return 0;
    }
    

    3.5 其他函数

    • 交换两个同类型容器的元素:swap(map&, map&);mp.swap(map&);
    #include "stdafx.h"
    #include <iostream>
    #include <map>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	map<int,string> mp1;
    	// 在容器中插入元素
    	mp1[1] = "张三";
    	mp1[2] = "李四";
    	mp1[3] = "隔壁老王";
    
    	map<int, string> mp2;
    	// 在容器中插入元素
    	mp2[1] = "tom";
    	mp2[2] = "jerry";
    	mp2[3] = "mariy";
    
    	// 交换两个容器的元素
    	mp2.swap(mp1);
    
    	// 通过iterator遍历mp1
    	map<int, string>::iterator it;
    	for (it = mp1.begin(); it != mp1.end(); it++)
    		cout << it->second << " "; // 输出:tom jerry mariy
    	cout << endl;
    
    	return 0;
    }
    

    四、迭代器与算法

    1. 迭代器

    • 开始迭代器指针:mp.begin();
    • 末尾迭代器指针:mp.end(); // 指向最后一个元素的下一个位置
    • 指向常量的开始迭代器指针:mp.cbegin(); // 意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。
    • 指向常量的末尾迭代器指针:mp.cend();
    • 反向迭代器指针,指向最后一个元素:mp.rbegin();
    • 反向迭代器指针,指向第一个元素的前一个元素:mp.rend();
    • 返回最后一个 key<=keyElem 元素的迭代器:mp.lower_bound(keyElem);
    • 返回第一个 key>keyElem 元素的迭代器:mp.upper_bound(keyElem);
    • 返回容器中 key 与 keyElem 相等的上下限的两个迭代器,这两个迭代器被放在对组(pair)中: mp.equal_range(keyElem);
    #include <iostream>
    #include <map>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char* argv[])
    {
    	map<int,string> mp;
    	// 在容器中插入元素
    	mp[1] = "张三";
    	mp[2] = "李四";
    	mp[3] = "隔壁老王";
    
    	cout << mp.begin()->first << endl; // 输出:1
    	cout << (--mp.end())->first << endl; // 输出:3
    	cout << mp.cbegin()->first << endl; // 输出:1
    	cout << (--mp.cend())->first << endl; // 输出:3
    	cout << mp.rbegin()->first << endl; // 输出:3
    	cout << (--mp.rend())->first << endl; // 输出:1
    	cout << mp.lower_bound(2)->first << endl; // 输出:2
    	cout << mp.upper_bound(2)->first << endl; // 输出:3
    	pair<map<int, string>::iterator, map<int, string>::iterator> t_pair = mp.equal_range(2);
    	cout << t_pair.first->first << endl; // 输出:2
    	cout << t_pair.second->first << endl; // 输出:3
    	cout << endl;
    
    	return 0;
    }
    

    2. 算法

    • 遍历元素
    map<int>::iterator it;
    for (it = mp.begin(); it != mp.end(); it++)
        cout << it->second << endl;
    

    五、总结

    可以看到,map 与set的用法基本一致,只有以下一处不同:

    • map 可以像数组那样插入元素,而 set 不行。

  • 相关阅读:
    html5 video标签如何禁止视频下载
    Redis源代码-数据结构Adlist双端列表
    HTML5分析实战WebSockets基本介绍
    Chromium on Android: Android在系统Chromium为了实现主消息循环分析
    Android AIDL使用特定的解释
    [LeetCode]Maximum Product Subarray
    OC省字典的数组摘要集
    CocoaChina 第四个测试
    Java在的时候,类定义HashSet初始化方法
    WSHPSRS-匹克选择列表生成器-SRS(R12.2.3)
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/10261263.html
Copyright © 2020-2023  润新知