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

C++ map、set 与关联式容器入门

C++ 的关联式容器主要包括 map、set、multimap、multiset,底层通常基于红黑树,特点是按 key 或 value 保持有序,适合查找、统计、去重这类场景。set 只存唯一值,multiset 允许重复;map 存键值对,multimap 允许重复键。文中还说明了 pair、insert、erase、count、find 以及 map 的 [] 操作符在不同场景下的行为,尤其是 [] 在 key 不存在时会插入默认值,常用于频次统计。

协议工匠发布于 2026/6/300 浏览
C++ map、set 与关联式容器入门

C++ 关联式容器概述

序列式容器和关联式容器

STL 里的容器,大体可以分成两类。

  1. 序列式容器:vector、list、deque、forward_list(C++11)等,元素按线性顺序存放,关注的是'把数据装起来'。
  2. 关联式容器:围绕 <key, value> 或 key 本身组织数据,更偏向'按键查数据'。

如果你经常做查找、统计、去重,这类容器通常比序列式容器更顺手。

键值对 <key, value>

键值对就是通过 key 找到 value 的结构。英汉字典是最常见的例子:英文单词是 key,中文释义是 value。这个模型本身不复杂,难点在于容器怎么把它组织好、查起来又快又稳。

树形结构的关联式容器

STL 里常见的树形关联式容器有四种:map、set、multimap、multiset。它们的底层通常是平衡搜索树,常见实现是红黑树,所以元素天然有序,遍历时拿到的是中序序列。

set 容器:只管 value,不管 pair

基本特征

set 按一定顺序存储元素,元素本身就是它的身份,也就是'value 即 key'。这意味着每个值都必须唯一,不能重复。

它有几个很实用的特点:

  • 元素不能在容器内部直接修改,只能插入或删除。
  • 默认按小于号比较,也就是升序排列。
  • 底层一般是红黑树,查找复杂度是 O(log n)。
  • 头文件是 <set>。

和 map 的区别

map / multimap 存的是真正的 <key, value>;set 只保存 value,但内部可以理解成 <value, value>。这也是为什么 set 插入时只需要给一个值,不用先拼 pair。

常见用途

set 最常见的场景就是去重和排序。把一组数丢进去,重复项会被自动过滤,遍历出来又是有序的。这个特性很朴素,但线上处理数据时特别省事。

删除时的几个细节

erase 有三种常见写法,行为不太一样:

  1. 按迭代器删除:删指定位置的元素;如果迭代器无效,程序就会出问题,所以通常先配合 find 判断。
  2. 按值删除:返回被删掉的个数。
  3. 按区间删除:区间是左闭右开,常配合 lower_bound 和 upper_bound 使用。

其中,lower_bound(k) 找的是第一个 >= k 的位置,upper_bound(k) 找的是第一个 > k 的位置。

multiset:允许重复的 set

multiset 和 set 很像,差别主要在是否允许重复值。

  • 元素按特定顺序存储。
  • 值可以重复。
  • 元素同样不能在容器中直接修改。
  • 底层通常也是红黑树。

它的接口和 set 基本一致,只是有几处行为会更贴近'多重集合'的语义:

  • erase 返回删除元素的个数。
  • count 返回某个值出现的次数。
  • find 返回中序遍历里第一次出现的位置。

map 容器:最常用的键值表

基本特征

map 存的是键值对,按 key 排序。

  • key 用来排序,也用来唯一标识元素。
  • value 保存关联内容。
  • 内部通常用 pair<const key, T> 表示一个元素。
  • 可以按顺序直接遍历。
  • 支持下标访问符 []。
  • 头文件是 <map>。

pair 模板类

pair 定义在 <utility> 头文件中,用来把两个不同类型的值绑在一起。make_pair 可以直接构造它,写起来更省事。

模板参数

map 的模板参数通常包括:

  1. key:键的类型。
  2. T:值的类型。
  3. Compare:比较器,默认按小于号比较;自定义类型时往往要自己传。
  4. Alloc:空间配置器,一般不用手动管。

insert 的用法

insert 常接收 value_type,也就是一个 pair。遍历时,别把它当成普通单值处理,得用 first 和 second 访问键和值。

如果是范围 for,建议带上引用,少一次拷贝,代码也更干净。

去重

map 会按 key 去重,key 相同的元素不能同时存在。字符串 key 的排序,通常就是按字符的 ASCII 顺序一路比下去。

multimap:允许重复 key

multimap 可以看作 map 的'宽松版',区别只有一个:key 可以重复。适合一对多的场景,比如一个分类下挂多个条目。

map 的 [] 操作符

[] 是 map 里最容易被顺手用坏的接口,但统计场景里它确实很方便。

计算水果出现次数

常见做法有三种:

  1. 用迭代器和 find:先查,再决定要不要插入或更新。
  2. 看 insert 的返回值:insert 会返回 pair<iterator, bool>,bool 表示是否插入成功,iterator 指向新插入或已经存在的结点。
  3. 直接用 []:
    • 如果 key 不存在,[] 会先插入一个默认构造的 value。
    • int 默认是 0,指针默认是 nullptr。
    • 逻辑上可以理解成先查找,找不到就补一个默认值,再返回 second。

所以像 mapCount[e]++ 这种写法,本质上就是把 e 对应的计数加一。它很适合做频次统计,写法短,也够直接。

目录

  1. C++ 关联式容器概述
  2. 序列式容器和关联式容器
  3. 键值对 <key, value>
  4. 树形结构的关联式容器
  5. set 容器:只管 value,不管 pair
  6. 基本特征
  7. 和 map 的区别
  8. 常见用途
  9. 删除时的几个细节
  10. multiset:允许重复的 set
  11. map 容器:最常用的键值表
  12. 基本特征
  13. pair 模板类
  14. 模板参数
  15. insert 的用法
  16. 去重
  17. multimap:允许重复 key
  18. map 的 [] 操作符
  19. 计算水果出现次数
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

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

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

更多推荐文章

查看全部
  • 大模型上下文窗口 200k 到底是什么
  • OpenClaw 橙皮书与蓝皮书实战笔记
  • 用 Rust 和 GLM-5 做一个流式翻译 CLI
  • Hunyuan-MT-7B-WEBUI 多语言翻译系统搭建与体验
  • Qwen3-Embedding-4B 本地部署:llama.cpp 与 vLLM 集成
  • Typora 的安装与基础设置
  • Web25 中 php_mt_seed 的爆破思路
  • 8 个 AI 平台的速度和 Token 消耗实测
  • MySQL 8.0.41 安装、配置与入门操作
  • ControlNet-sd21 的入门与实战思路
  • LFM2-1.2B:面向边缘设备的混合模型整理
  • 贪心算法和动态规划:原理、区别与 C++ 示例
  • 前缀和解子数组计数:和为 K 与可被 K 整除
  • 用 FastAPI 搭一个 SSE MCP 服务
  • HTML 入门:结构、常用标签与 HTML5 要点
  • 用 PyMobileDevice3 管理 iOS 设备
  • 在 Linux 上把 OpenClaw 接到 QQ 机器人
  • Linux 下用 gdb 和 cgdb 调试 C/C++
  • LeetCode 962 最大宽度坡的 C 语言做法
  • 用 ImGui 快速搭一个 C++ 调试面板

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

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

  • Base64 文件转换器

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