元数据卡
- 前置知识:第1章 命题逻辑
- 预计时间:45 分钟
- 核心难度:入门
- 完成标志:掌握集合的表示与运算,理解维恩图和集合恒等式
你的进度
上一步你学会了用逻辑符号精确表达判断。馆长带你上到二层——这里的石门上有许多圆形的符号和花括号。每个符号都指向一组对象。
你的任务
"找出所有成绩在 80 分以上的学生"——这类操作在数据库中每天发生几百万次。你在做的其实是一件事:从一个集合中找出满足条件的子集。理解集合,就是理解数据筛选、分类和组合的本质。
本章分层
- 必读:集合的基本概念,子集、并集、交集、补集
- 选读:集合恒等式与代数的证明
破局 · 溯源
你在写一个处理用户列表的程序。有一个 List A 包含管理员,List B 包含所有活跃用户。你想找到既是管理员又活跃的用户,也想找到所有管理员加上活跃用户的并集,还想找到标记为删除但不在活跃列表中的用户。这些操作在数学上统一为集合运算——你在编程中已经不知不觉在用,现在是时候系统化地理解了。
集合是由确定的对象组成的整体。用花括号表示:
- A =
- B = {x | x 是偶数, x > 0} —— 这是集合构造器写法,读作"所有满足条件的 x"
一个对象要么属于集合(∈),要么不属于(∉)。没有中间状态。这看起来简单,但恰恰是计算机数据结构的基础——哈希表告诉你某个键是否存在,二分查找告诉你在不在有序数组中,这些都是"属于"判断的具体实现。
子集:A ⊆ B 表示 A 中的所有元素都是 B 的元素。空集 ∅ 是任何集合的子集。
运算:
| 运算 | 符号 | 结果 |
|---|---|---|
| 并集 | A ∪ B | 所有属于 A 或 B 的元素 |
| 交集 | A ∩ B | 属于 A 和 B 的元素 |
| 差集 | A \ B | 属于 A 但不属于 B 的元素 |
| 补集 | Aᶜ | 全集 U 中不属于 A 的元素 |
一个真实场景:你有一个所有用户的集合 U,一个购买过某商品的集合 B。你想做"向未购买的活跃用户推送广告":
活跃用户 = U ∩ 最近登录用户
推送对象 = 活跃用户 \ B对应到 SQL 就是 SELECT * FROM active_users WHERE user_id NOT IN (SELECT user_id FROM buyers)。SQL 的 JOIN、UNION、EXCEPT、INTERSECT 都是集合运算的直接映射。
集合恒等式是逻辑等式的集合版。比如德·摩根定律在集合论中是:
- (A ∪ B)ᶜ = Aᶜ ∩ Bᶜ
- (A ∩ B)ᶜ = Aᶜ ∪ Bᶜ
验证方式有两个:画维恩图(直观),或者用逻辑证明(严谨)。后者的思路是:要证明两个集合相等,证明它们互为子集。
常见陷阱
- 混淆元素和子集。{1} 是包含整数 1 的集合,1 是元素。{1} ⊆ 1 是假的,因为 1 的元素是 {1}(一个集合),而 1 不是这个集合的元素。
- 空集不等于"无"。∅ = {},但 {∅} 是一个包含空集的集合——它不是空集。
- 在计算机科学中,集合通常要求元素是 hashable 的。在数学中集合可以包含任何东西,但在编程中不是所有类型都能放进 HashSet。
通关挑战
- 给定 A = {1, 2, 3}, B = {2, 3, 4}, C = {1, 3, 5},求 (A ∪ B) ∩ C。
- 证明 A \ (B ∪ C) = (A \ B) ∩ (A \ C)。
- 用 Python 的 set 类型实现差集运算,并对比数学差集和编程差集的异同。
旅人笔记
集合论给了你描述"哪些东西"的语言。逻辑处理真值,集合处理元素——两者借由"属于"关系紧密相连,是所有后续数学讨论的基石。
→ 下一站预告:有了逻辑和集合,你开始有能力验证一个命题是否总是成立——这引出了第三层:证明方法。