Delphi 编程 -- 再谈集合类型
Delphi 编程 -- 再谈集合类型
上一次我们简单介绍了 Delphi 中的集合类型,今天我们讨论一下集合的操作。注:在以下的讨论中,我们规定大写字母(如 A、B、C 等)表示集合,小写字母(如 a、b、c 等)表示集合的元素。在数学的集合论中,集合的操作有交集(A ∩ B)、并集(A ∪ B)、差集(A / B),判断集合之间包含关系的子集(A ⊂ B)以及元素与集合之间隶属关系的属于(a ∈ A)等。与数学中的集合相似,Delphi 中也提供了集合之间的操作:- 子集:A <= B,表示 A 是 B 的子集,即 A 的所有元素同时也是 B 的元素。
- 扩张集:A >= B,表示 A 是 B 的扩张集(超集),即 A 包含了 B 的所有元素,即 B <= A。
- 相等:A = B,表示 A 与 B 包含相同的元素。
- 不等:A <> B,表示 A = B 不成立,即 A 与 B 包含的元素不相同。
在这个例子中,首先定义了 TFontStyle 枚举类型,里面包含了几种字体风格,然后以 TFontStyle 为基类型定义了 TFontStyleSet 集合类型。这表示 TFontStyleSet 类型的变量都将在 TFontStyle 中取值。接着,声明了两个 TFontStyleSet 类型的变量 FSA 和 FSB。在接下来的语句部分,首先将 FSA 变量初始化为空集。注意:数学上表示集合是用大括号({}),因为大括号已经被 Pascal 用来表示注释,所以集合在 Pascal 语言中就用中括号([])来表示。每行语句后面的注释我们还是采用数学上的表示法。然后,在第14行,用 FSA + [fsBold] 表示集合 FSA 和 [fsBold] 的并集。注意:与数学相同,Pascal 中也可以用将元素用集合符号括起来的形式表示集合,这里的 [fsBold] 就表示含有一个 fsBold 元素的集合,这个集合没有名字。因为 FSA 为空集,并集之后,FSA 就有了一个元素:fsBold。此时的 FSA 就是一个单元素集合。第15行,继续进行并集操作。[fsBold, fsItalic] 表示一个含有两个元素 fsBold 和 fsItalic 的无名集合,与 FSA 进行并集操作,注意,因为此时 FSA 中已经含有 fsBold 元素,与 [fsBold, fsItalic] 进行并集操作之后,FSA 中并不会含有两个 fsBold 元素,因为集合不能含有重复元素,所以,在进行并集操作时,只是将 [fsBold, fsItalic] 中不在 FSA 中的元素并入到 FSA 中。故并集操作之后,FSA = {fsBold, fsItalic}。接下来的第 16、17、18 行是测试元素 fsItalic 是否属于 FSA 集合。通过以上的并集操作,我们知道,FSA 中含有 fsBold 元素,所以测试的结果是真的。第21行是集合赋值,此语句执行以后,FSB 将含有与 FSA 相同的元素,因此第22行测试 FSB 与 FSA 是否相等的结果即为真。第24行是差集操作,求 FSB 和 [fsBold] 集合的差集,也就是从 FSB 集合中减去 [fsBold] 集合的元素,差集的结果是 FSB = {fsItalic}。第25行测试 FSB 是否 FSA 的子集,因为此时 FSA = {fsBold, fsItalic}。因此 FSB ⊂ FSA。第27行,Include(FSB, fsUnderline),这个操作是将 fsUnderline 元素直接加到 FSB 集合中,相当于 FSB := FSB + [fsUnderline],但实现效率比 + 所表示的并集操作效率高。此时 FSB = {fsItalic, fsUnderline}。因为此时 FSB 含有与 FSA 不同的元素,所以接下来的相等以及子集测试都是不成功的。Exclude 是 Include 的对偶操作,Exclude(FSB, fsItalic) 是将元素 fsItalic 从 FSB 集合中剔除,相当于 FSB := FSB - [fsItalic] 差集操作,但实现效率要比 - 所表示的差集操作效率高。剔除后,FSB = {fsUnderline}。此时再测试 FSB 中是否包含 fsItalic,答案肯定是否。从这个简单例子可以看出,集合类型对于某些隶属关系的操作与测试还是很方便的。枚举类型 TFontStyle 有 4 个值,所以其子集个数有 16 个,也就是说,TFontStyleSet 的值空间为下面列出的集合:- 1 元素集,4 个:{fsBold}, {fsItalic}, {fsUnderline}, {fsStrikeThrough}
- {fsBold, fsItalic}, {fsBold, fsUnderline}, {fsBold, fsStrikeThrough}
- {fsItalic, fsUnderline}, {fsItalic, fsStrikeThrough}
- {fsUnderline, fsStrikeThrough}
- {fsBold, fsItalic, fsUnderline}
- {fsBold, fsItalic, fsStrikeThrough}
- {fsItalic, fsUnderline, fsStrikeThrough}
- {fsBold, fsUnderline, fsStrikeThrough}
- {fsBold, fsItalic, fsUnderline, fsStrikeThrough}
所以,上面代码中的集合 FSA 或 FSB 的取值只能是上面列出的这些集合。根据集合论,set of T 的值空间(即类型 set of T 的变量的取值范围)为 T 的幂集 𝓟(T)。如果 T 含有 n 个值,则 𝓟(T) 含有 2ⁿ 个值。
本文来自网友投稿或网络内容,如有侵犯您的权益请联系我们删除,联系邮箱:wyl860211@qq.com 。