delphi 集合類型探究


集合是由具有某些共同特征的元素構成的一個整體。在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個字節,分別取出來,原理也是一樣的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM