仓库链接
本仓库提供STL相关每一篇文章的完整可运行示例代码。

git clone https://github.com/MaikieMaiky/cpp_STL.git

map 基本概念

map 是一个按 key 自动排序的键值对容器

每个元素本质上都是一个 pair

  • first:key,起到索引作用
  • second:value,表示 key 对应的值
map<string, int> score;

可以理解为:

姓名 -> 分数
单词 -> 出现次数
编号 -> 对象

特点:

  1. map 属于关联式容器,底层通常是红黑树
  2. 所有元素会按照 key 自动排序
  3. map 不允许重复 key,multimap 允许重复 key
  4. 查找、插入、删除的效率通常是 O(log n)

常见用途:

  • 建立映射关系:姓名 -> 年龄、学号 -> 学生信息
  • 统计次数:数字 -> 出现次数、单词 -> 出现次数

map 构造和赋值

原型:

  • map<T1, T2> mp; // 默认构造函数
  • map(const map &mp); // 拷贝构造函数
  • map& operator=(const map &mp); // 重载等号操作符

补充:map<T1, T2> 中,T1 是 key 的类型,T2 是 value 的类型。

  • 示例

    // map构造和赋值
    /**
     * map<T1, T2> mp;                      // 默认构造函数
     * map(const map &mp);                  // 拷贝构造函数
     * map& operator=(const map &mp);       // 重载等号操作符
     *
     * map容器特点:
     * 1. map中所有元素都是pair
     * 2. pair中第一个元素为key,起到索引作用,第二个元素为value
     * 3. 所有元素都会根据元素的key自动排序
     */
    #include <iostream>
    #include <map>
    
    using namespace std;
    
    void print_map(const map<int, int>& m)
    {
        for (auto &p : m)
        {
            cout << "key = " << p.first << " value = " << p.second << endl;
        }
        cout << endl;
    }
    
    void test0()
    {
        // 1. 默认构造
        map<int, int> m1;
    
        // map容器插入数据需要使用pair
        m1.insert({1, 10});
        m1.insert(pair<int, int>(2, 20));
        m1.insert(pair<int, int>(3, 30));
        m1[4] = 40;
        cout << "m1 = " << endl;
        print_map(m1);
    
        // 2. 拷贝构造
        map<int, int> m2(m1);
        cout << "m2 = " << endl;
        print_map(m2);
    
        // 3. 赋值
        map<int, int> m3;
        m3 = m1;
        cout << "m3 = " << endl;
        print_map(m3);
    }
    
    int main()
    {
        test0();
        return 0;
    }
    

map 大小和交换

原型:

  • size(); // 返回容器中元素的数目

  • empty(); // 判断容器是否为空

  • swap(mp); // 交换两个 map 容器

  • 示例

    // map大小和交换
    /**
     * size();      // 返回容器中元素的数目
     * empty();     // 判断容器是否为空
     * swap(mp);    // 交换两个map容器
     */
    #include <iostream>
    #include <map>
    
    using namespace std;
    
    void print_map(const map<int, int>& m)
    {
        for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++)
        {
            cout << "key = " << (*it).first << " value = " << (*it).second << endl;
        }
        cout << endl;
    }
    
    void test0()
    {
        map<int, int> m1;
        m1.insert(pair<int, int>(1, 10));
        m1.insert(pair<int, int>(2, 20));
        m1.insert(pair<int, int>(3, 30));
    
        if (m1.empty())
        {
            cout << "m1 is empty" << endl;
        }
        else
        {
            cout << "m1 is not empty" << endl;
            cout << "m1 size = " << m1.size() << endl;
        }
    }
    
    void test1()
    {
        map<int, int> m1;
        m1.insert(pair<int, int>(1, 10));
        m1.insert(pair<int, int>(2, 20));
        m1.insert(pair<int, int>(3, 30));
    
        map<int, int> m2;
        m2.insert(pair<int, int>(4, 40));
        m2.insert(pair<int, int>(5, 50));
        m2.insert(pair<int, int>(6, 60));
    
        cout << "before swap:" << endl;
        cout << "m1 = " << endl;
        print_map(m1);
        cout << "m2 = " << endl;
        print_map(m2);
    
        m1.swap(m2);
    
        cout << "after swap:" << endl;
        cout << "m1 = " << endl;
        print_map(m1);
        cout << "m2 = " << endl;
        print_map(m2);
    }
    
    int main()
    {
        test0();
        test1();
        return 0;
    }
    

map 插入和删除

原型:

  • insert({key, value}); // 插入键值对,key 一样则插入失败
  • insert(make_pair(key, value)); // 插入键值对
  • operator[](key) = value; // 通过 [] 插入或修改,key 一样则覆盖 value
  • erase(pos); // 删除 pos 迭代器所指的元素
  • erase(beg, end); // 删除区间 [beg, end) 的元素
  • erase(key); // 删除 key 对应的元素
  • clear(); // 清除所有元素

注意:

  • insert:key 已存在,不覆盖

  • []:key 已存在,会修改 value

  • 如果只是查询 key 是否存在,不建议用 [],因为 key 不存在时会自动插入默认值

  • 示例

    // map插入和删除
    /**
     * insert({key, value});                            // 在容器中插入元素 key一样则插入失败
     * insert(make_pair(key, value));                   // 在容器中插入元素 key一样则插入失败
     * insert(pair<int, int>(key, value));              // 在容器中插入元素 key一样则插入失败
     * insert(map<int, int>::value_type(key, value));   // 在容器中插入元素 key一样则插入失败
     * operator[](key) = value;                         // 通过[]方式插入/修改元素 key一样则覆盖value
     * erase(pos);                                      // 删除pos迭代器所指的元素,返回下一个元素的迭代器
     * erase(beg, end);                                 // 删除区间[beg, end)的所有元素,返回下一个元素的迭代器
     * erase(key);                                      // 删除容器中key对应的元素
     * clear();                                         // 清除所有元素
     */
    #include <iostream>
    #include <map>
    
    using namespace std;
    
    void print_map(const map<int, int>& m)
    {
        for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++)
        {
            cout << "key = " << it->first << " value = " << it->second << endl;
        }
        cout << endl;
    }
    
    void test0()
    {
        map<int, int> m1;
    
        // 1. insert
        m1.insert(pair<int, int>(1, 10));
        m1.insert(make_pair(2, 20));
        m1.insert(map<int, int>::value_type(3, 30));
        m1[4] = 40;
        cout << "m1 = " << endl;
        print_map(m1);
    
        // 2. erase(pos)
        m1.erase(m1.begin());
        cout << "m1 = " << endl;
        print_map(m1);
    
        // 3. erase(beg, end)
        m1.erase(++m1.begin(), m1.end());
        cout << "m1 = " << endl;
        print_map(m1);
    
        // 4. erase(key)
        m1.erase(2);
        cout << "m1 = " << endl;
        print_map(m1);
    
        // 5. clear
        m1.clear();
        cout << "m1 = " << endl;
        print_map(m1);
    }
    
    int main()
    {
        test0();
        return 0;
    }
    

map 查找和统计

原型:

  • find(key); // 查找 key 是否存在,存在则返回该元素迭代器,不存在返回 map.end()
  • count(key); // 统计 key 的元素个数

注意:对于 mapcount(key) 的结果只能是 01,因为 map 不允许重复 key。

  • 示例

    // map查找和统计
    /**
     * find(key);      // 查找key是否存在,若存在返回该键的元素的迭代器,若不存在返回map.end()
     * count(key);     // 统计key的元素个数
     *
     * 对于map容器,count(key)的结果只能是0或1,因为map不允许插入重复key。
     */
    #include <iostream>
    #include <map>
    
    using namespace std;
    
    void test0()
    {
        map<int, int> m1;
        m1.insert({1, 10});
        m1.insert({2, 20});
        m1.insert({3, 30});
        m1.insert({4, 40});
    
        // 1. find
        map<int, int>::iterator pos = m1.find(3);
        if (pos != m1.end())
        {
            cout << "find the element: key = " << pos->first << " value = " << pos->second << endl;
        }
        else
        {
            cout << "not find the element" << endl;
        }
    
        map<int, int>::iterator pos2 = m1.find(30);
        if (pos2 != m1.end())
        {
            cout << "find the element: key = " << pos2->first << " value = " << pos2->second << endl;
        }
        else
        {
            cout << "not find the element" << endl;
        }
    
        // 2. count
        int num = m1.count(3);
        cout << "the number of key 3 is: " << num << endl;
    }
    
    int main()
    {
        test0();
        return 0;
    }
    

map 排序

原型:

  • map<T1, T2, Compare> mp; // 创建 map 容器时指定排序规则

说明:

  • map 默认按照 key 从小到大排序

  • 可以通过仿函数改变排序规则

  • 内置数据类型可以使用 greater<T> 实现降序

  • 示例

    // map排序
    /**
     * map<T1, T2, Compare> mp;     // 创建map容器时指定排序规则
     *
     * map容器默认按照key从小到大排序。
     * 利用仿函数可以改变map容器的排序规则。
     * 内置数据类型可以使用greater<T>来生成仿函数
     */
    #include <iostream>
    #include <map>
    
    using namespace std;
    
    class my_compare
    {
    public:
        bool operator()(int v1, int v2) const
        {
            return v1 > v2; // 降序
        }
    };
    
    void print_map(const map<int, int, my_compare>& m)
    {
        for (map<int, int, my_compare>::const_iterator it = m.begin(); it != m.end(); it++)
        {
            cout << "key = " << it->first << " value = " << it->second << endl;
        }
        cout << endl;
    }
    
    void test0()
    {
        // 在创建时就要指定排序规则
        map<int, int, my_compare> m1;
        // map<int, int, greater<int>> m1;
        m1.insert({1, 10});
        m1.insert({2, 20});
        m1.insert({3, 30});
        m1.insert({4, 40});
        m1.insert({5, 50});
    
        cout << "m1 = " << endl;
        print_map(m1);
    }
    
    int main()
    {
        test0();
        return 0;
    }
    

更多推荐