集合是由具有某些共同特征的元素構成的一個整體。在pascal中,一個集合是由具有同一有序類型的一組數據元素所組成,這一有序類型稱為該集合的基類型。
一、集合類型的定義和變量的說明
集合類型的一般形式為:
set of 基類型;
基類型可以是任意順序類型, 而不能是實型或其它構造類型。同時,基類型的數據的序號不得超過255。例如下列說明是合法的:
type numbers =set of 0..9; ch=set of char; day=(sun,mon,tue,wed,thu,fri,sat); var s: numbers; c:ch; weekday:day;
可以將類型說明與變量說明合並在一起,如:
var s:set of 0..9; { 子界型 } c:set of char; weekday: (sun,mon,tue,wed,thu,fri,sat); { 枚舉型 }
注意:集合的元素個數不超過256個,因此 var s:set of integer; 是錯誤的。
二、集合的值
1、集合的值放在一對方括號中,中間各元素之間用逗號隔開。如:[1,2,5] 和 ['a','e','i'] 都是集合。
2、在集合中可以沒有任何元素,這樣的集合稱為空集。[] 空集
3、在集合中,如果元素的值是連續的,則可用子界型的表示方法表示。例如:
[1,2,3,4,5, 10,15] 可以表示成: [1..5,10,15]
4、集合的值與方括號內元素出現的次序無關。例如[1,5,8 ]和[5,1,8]的值相等。
5、在集合中同一元素的重復出現對集合的值沒有影響。例如,[1,8,5,1,8]與[1,5,8]的值相等。
6、每個元素可用基類型所允許的表達式來表示。如 [1,1+2,4]、[succ(ch)]。
三、集合的運算
集合類型變量不能進行算術運算,集合是無序的,不能使用ord、pred、succ等函數。
1、賦值運算
只能通過賦值語句給集合變量賦值,不能通過讀語句賦值,也不能通過寫語句直接輸出集合變量的值。如:
集合變量賦值: c:=['2']; i:=[5]; w:=[];
集合變量賦子界值: c:=['a'..'z']; i:=[1..7];
集合變量賦枚舉值: c:=['a','b','d','m']; i:=[2,4,6,8,10];
函數賦值操作:添加一個集合元素 Include(s, 1);
刪除一個集合元素 Exclude(s, 1);
2、集合的並、交、差運算
可以對集合進行並(+)、交(*)、差 (-)三種運算,每種運算只有一個運算符、兩個運算對象,運算結果仍為集合。注意它們與算術運算的區別。
① 並運算 (關系代數運算符∪)
A,B為兩個集合,由集合A中的元素加上集合B中的與A不重復的所有元素組成的集合,稱為集合A和B的並。即A+B,如:
[X,Y,Z]+[X] 為 [X,Y,Z] { 兩個集合中不重復的所有元素 }
[1]+[4] 為[1,4]
② 交運算 (關系代數運算符∩)
A,B為兩個集合,由既屬於集合A中的元素又屬於集合B中的所有元素組成的集合,稱為集合A和B的交。即A*B,如:
[X,Y,Z]*[X] 為 [X] { 兩個集合中的相同元素 }
[X,Y,Z]*[M] 為 []
③差運算 (關系代數運算符-)
A,B為兩個集合,由集合A中的元素除去集合B中與A相同的元素組成的集合,稱為集合A和B的差。即AB,如:
[X,Y,Z]-[X] 為 [Y,Z ] { 在集合A中又不在集合B中的所有元素 }
[X,Y,Z]-[M] 為 [X,Y,Z]
3、集合的關系運算: 運算結果為布爾值
關系運算符:= 相等、 <> 不相等
>= 包含,表示前者蘊含后者,相當於集合論中的 <V:FORMULAS>FORMULAS>。
<= 包含於,表示前者蘊含於后者,相當於集合論中的 。
例如:[a,b,c]=[b,c,a] 為true,元素個數相同,內容相同,不管排列順序如何。
[a,b,c]>=[a] 為true;
[a,b]<=[a,b,c] 為true。
in運算:in的右邊為集合,左邊為與集合基類型相同的表達式,為布爾值。in測試一個元素是否在集合中。相當於集合論中的∈。它們都是二目運算,且前4個運算符的運算對象都是相容 的集合類型。例如:a in[b,c] 為false。
設集合a:=[1..10]; x 為integer,如x在集合a中即刪除a中的元素x,否則把元素x添加到集合a中。程序段如下:
if x in a then a:=a-[x] else a:=a+[x]
例1、設全集E={1,2,3,4,5},集合A={1,4},B={1,2,5},C={2,4},則集合
(A∩B)∪~C 為( )。 ( NOIP2003單選8 )
A)空集 B){1} C){3,5} D){1,5} E){1,3,5}
以上內容自轉載:delphi語法基礎--集合類型 http://www.xuedelphi.cn/wenzhang/pascal/2007/12/200712302017_2.htm
以下內容為探究的內容:
首先我們來看一個問題,
var sd: set of 1..9; t: set of 1..60; begin sd := []; // sd = [] sd := [1,2]; // sd = [1,2] sd := sd + [15]; // sd = [1,2,15] 按照定義,sd應該為1到9的值, // 15應該不能加進來,但實際能加進去,使用 Include(sd, 15)也是一樣 sd := sd + [16]; // sd = [1,2,15] 發現大於16的數字無法添加進集合內 sd := sd + [25]; // sd = [1,2,15] sd := []; showmessage(inttostr(sizeof(sd))); // 輸出 2 showmessage(inttostr(sizeof(t))); // 輸出 8 end;
出現這種現象,我們從集合類型的在內存中存儲結構來解析,集合的元素在內存中是按位來存儲的,並以整數字節為存儲單元,
比如 sd: set of 1..9 它在內存中需要9位來存儲,超過一個字節8位,所以內存中是分配給2個字節存儲空間。
我們可以通過
showmessage(inttostr(PWord(@sd)^))
來顯示他在內存中的值。
比如 sd = [1,3,5,6]時,按照前面說的,對應二進制數為:1101010,就是第1位、第3位、第5位、第6位為1,對應十進制為106。
位是從第0位開始的,所以第零位也表示一個值。按照此原理,反過來,如果利用下面語句:
PWord(@sd)^ := 106;
得到的是sd也是[1,3,5,6],如果sd: set of 1..60 ,則在內存中占8個字節,分別取出來,原理也是一樣的。