跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++算法

STL map 与 multimap 深度解析:接口、特性与实战应用

STL map 基于红黑树实现,存储键值对,支持 O(logN) 查找。重点掌握 insert、find、operator[] 用法及 key 不可修改原则。multimap 允许重复键但不支持 operator[]。常见场景包括词频统计、链表复制及 Top K 问题。代码示例展示了如何高效利用 map 进行数据处理。

w795471发布于 2026/3/15更新于 2026/6/1519 浏览
STL map 与 multimap 深度解析:接口、特性与实战应用

STL map 和 multimap 是关联式容器中的核心成员,底层基于红黑树实现。与 set 不同,它们存储的是键值对(pair),支持通过 key 快速映射到 value。

map 类基础

map 的模板声明如下:

template <class Key,      // map::key_type
class T,                  // map::mapped_type
class Compare = less<Key>,// map::key_compare
class Alloc = allocator<pair<const Key,T>>> // map::allocator_type
class map;

关键参数:

  • Key:键类型,必须唯一。
  • T:映射值的类型。
  • Compare:比较仿函数,默认按 key 升序排列。
  • Alloc:空间配置器。

底层特性:

  • 结构:平衡二叉搜索树(红黑树)。
  • 复杂度:增删查改均为 O(logN)。
  • 遍历:中序遍历,key 有序。
  • 限制:支持修改 value,严禁修改 key(会破坏树结构)。

pair 类型详解

map 节点实际存储的是 pair<const Key, T>。pair 将两个数据组合成一个单元:

template<class T1, class T2>
struct pair {
    typedef T1 first_type;
    typedef T2 second_type;
    T1 first;   // key
    T2 second;  // value
    
    pair() : first(T1()), second(T2()) {}
    pair(const T1& a, const T2& b) : first(a), second(b) {}
};

使用要点:

  • first 访问 key(const,不可改)。
  • second 访问 value(可改)。
  • 推荐用 make_pair() 或 {key, value} 初始化列表创建对象。

构造与迭代器

构造方式

  1. 无参默认构造。
  2. 迭代器区间构造。
  3. 拷贝构造。
  4. 初始化列表构造(最常用)。
map<string, string> dict = {{"left", "左边"}, {"right", "右边"}};

迭代器操作

  • begin()/end():正向遍历,指向最小 key。
  • rbegin()/rend():反向遍历,指向最大 key。
  • 双向迭代器,支持 ++/--。
  • 遍历时可直接修改 it->second,但不可动 it->first。

增删查操作

插入

insert() 返回 pair<iterator, bool>,指示是否插入成功。若 key 已存在,即使 value 不同也会失败。

auto ret = dict.insert({"new_key", "value"});
if (ret.second) {
    // 插入成功
}

查找

  • find(k):返回迭代器,未找到返回 end()。
  • count(k):map 中返回 0 或 1。

删除

  • erase(pos):删除迭代器位置元素。
  • erase(k):删除指定 key 的元素,返回删除个数。
  • erase(first, last):删除区间元素。

边界查找

  • lower_bound(k):返回 >= k 的第一个元素。
  • upper_bound(k):返回 > k 的第一个元素。
  • equal_range(k):返回 [lower_bound, upper_bound) 范围。

核心特性:数据修改

迭代器修改 value

通过 find 获取迭代器后,直接修改 second 成员:

auto it = dict.find("left");
if (it != dict.end()) {
    it->second = "新内容"; // 合法
    // it->first = "right"; // 非法,编译错误
}

operator[] 的多功能用法

operator[] 是 map 的灵魂接口,集插入、查找、修改于一身。

mapped_type& operator[](const key_type& k);

原理: 内部调用 insert,若 key 不存在则插入默认构造的 value,然后返回 value 引用。

场景:

  1. 插入:key 不存在时,自动插入 {key, default_value}。
  2. 修改:key 存在时,直接赋值修改 value。
  3. 查找:返回 value 引用。
map<string, int> countMap;
countMap["apple"]++; // 不存在则插入 0 再自增,存在则自增

实战案例

词频统计

利用 operator[] 的简洁性统计单词出现次数:

string arr[] = {"苹果", "西瓜", "苹果", "香蕉"};
map<string, int> counts;
for (const auto& s : arr) {
    counts[s]++; // 一行搞定查找 + 插入 + 修改
}

复杂链表复制(LeetCode 138)

建立原节点到拷贝节点的映射,解决 random 指针问题:

class Solution {
public:
    Node* copyRandomList(Node* head) {
        map<Node*, Node*> nodeMap;
        Node* cur = head;
        while (cur) {
            nodeMap[cur] = new Node(cur->val);
            cur = cur->next;
        }
        cur = head;
        while (cur) {
            if (cur->random) nodeMap[cur]->random = nodeMap[cur->random];
            cur = cur->next;
        }
        return nodeMap[head];
    }
};

Top K 高频单词(LeetCode 692)

结合 map 排序特性与 priority_queue 或 sort 解决:

class Solution {
public:
    struct Compare {
        bool operator()(const pair<string,int>& x, const pair<string,int>& y) const {
            return x.second < y.second || (x.second == y.second && x.first > y.first);
        }
    };
    vector<string> topKFrequent(vector<string>& words, int k) {
        map<string, int> countMap;
        for (auto& w : words) countMap[w]++;
        priority_queue<pair<string,int>, vector<pair<string,int>>, Compare> pq(countMap.begin(), countMap.end());
        vector<string> res;
        while (k-- && !pq.empty()) {
            res.push_back(pq.top().first);
            pq.pop();
        }
        return res;
    }
};

multimap 的使用

multimap 允许 key 重复,其他接口与 map 基本一致。

特性mapmultimap
键值冗余❌ 不支持✅ 支持
insertkey 存在失败总是成功
find返回任意返回第一个
erase(key)删除 0/1 个删除所有匹配
operator[]✅ 支持❌ 不支持

注意: multimap 不支持 operator[],因为无法确定返回哪个重复 key 对应的 value 引用。

总结

  1. map 基于红黑树,key 唯一且有序,O(logN) 效率。
  2. 修改限制:只能改 value,不能改 key。
  3. operator[] 是最常用的接口,兼具插入与查找功能。
  4. multimap 支持重复 key,但不支持 operator[]。
  5. 应用场景:词频统计、复杂指针映射、Top K 问题等。

掌握这些特性,能让你在处理键值映射问题时游刃有余。

目录

  1. map 类基础
  2. pair 类型详解
  3. 构造与迭代器
  4. 构造方式
  5. 迭代器操作
  6. 增删查操作
  7. 插入
  8. 查找
  9. 删除
  10. 边界查找
  11. 核心特性:数据修改
  12. 迭代器修改 value
  13. operator[] 的多功能用法
  14. 实战案例
  15. 词频统计
  16. 复杂链表复制(LeetCode 138)
  17. Top K 高频单词(LeetCode 692)
  18. multimap 的使用
  19. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Unsloth 多场景适配:Llama、Qwen、Gemma 统一微调教程
  • Android 插件化技术:动态创建 Activity 模式详解
  • Linux vi/vim 编辑器基础使用指南
  • OpenClaw 多飞书机器人配置指南
  • Python AI 开发环境搭建:Anaconda + PyCharm + Claude Code 配置
  • Android 插件化框架 DynamicLoadApk 源码解析(下)
  • Linux System V 共享内存实战:底层原理、封装与避坑指南
  • Selenium 自动化中如何获取折叠面板内的内容
  • Android 插件化框架 DynamicLoadApk 源码解析(上)
  • NVIDIA RTX PC 开源 AI 工具升级:加速 LLM 与扩散模型性能
  • Blender 集成 AI 绘画插件实战:AI-Render 使用指南
  • Windows 部署 OpenClaw 集成 DeepSeek 与飞书实现本地 AI 控制
  • 渗透测试概述与标准实施流程
  • 开源双轴张力控制低成本墙绘机系统
  • 知网 2026 年 AIGC 检测算法升级与应对指南
  • VSCode 集成 Copilot 与 Figma MCP 生成产品代码
  • Android 不规则封闭区域填充色彩实现
  • 详解 Java 中的 @Schema 注解
  • Spring Web MVC 入门:注解用法、参数传递与 Postman 测试
  • MySQL 与 Navicat Windows 安装配置实战指南

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online