3-1.结构类型之集合类型

3-1.集合类型
集合类型是一群具有相同类型的元素的组合,这些类型必须是有限类型,如整型、布尔型、字符型、枚举型和子界类型。
集合类型的声明方法

set of 基类型;

请看以下代码:

type
    Set1=set of ’A’.. ’Z’; //基类型是子界型
    Set2=set of Char; //基类型是字符型
    Set3=set(Jan,Feb,Mar,Apr); //基类型是枚举型

Object Pascal 语言提供了几个用于集合的运算符,用这些运行符可以判断集合与集合之间的关系,例如对集合增删元素,求交集运算等。

一个集合类型的变量的值实际上是它的基类型的一个子集,可以为空集。一个集合最多可有256个元素。因此下面的集合定义是错误的:

 type SET1= Set Of Integer;

这是因为Integer集合的元素个数远远大于256。Pascal使用方括号来表示集合,例如: [Democrat];表示只含Democrat的集合。

示例:

Type

    TCharSet = Set of char;

    TEnum = (Monday, Tuesday, wednesday,Thursday,Friday,Saturday,Sunday);

    TEnumSet = set of TEnum ;

  var

    CharSet : TCharSet ;

    EnumSet : TEnumSet;

    SubrangeSet : set of 1..10;

    AlphaSet : Set of 'A'..'Z';

  begin

    CharSet := ['A'..'J','a','m'];

    EnumSet := [Saturday, Sunday];

    SubrangeSet := [1,2,4..6];

    AlphaSet :=[];

  end;

一个集合可以拥有0个元素,这时称之为空集,用两个方括号表示,其中什么也没有。对于集合类型变量,你可以进行+,-,=,*(并),IN等运算。见下表1-7.2。
 集合类型运算

操作符 描述 举例
+ 往一个集合中添加元素 Aset:=Aset+AnotherSet;
- 从一个集合中去除元素 Aset:=Aset-AnotherSet;
* 去除两个集合中都没有的元素 Aset:=Aset*AnotherSet;
In 测试元素 Bool:=AnElement in Aset

下面是集合运算的例子:

复制代码
Voter:=[HighOption];
Voter:=Voter+[Democrat]; 
Voter:=Voter+{male};
Voter:=Voter-[HighOption]; 

If HighOption in Voter then 
  SendtheVoterFlowers;
复制代码

并运算:A集合+B集合中不在A集合中的元素,并生成新的集合C

[A,B,C] + [B,C,D] = [A,B,C,D]

交运算:排除A集合与B集合中不相同的元素,并生成新的集合C

[A,B,C] * [B,C,D] = [B,C]

差运算:在A集合中除去B集合中与A集合中相同的元素,生成新的集合C

[A,B,C] - [B,C,D] = [A] 

 

赋值运算与简单类型一样,声明了一个集合类型的变量后,要为这个变量设定一个明确的值,例如:

var
    TInt1,Tint2:set of 1..10;

以上代码虽然声明了两个集合变量,但变量TInt1 和TInt2 并不是代表1-10 组成的集合,必须对它们赋值:

TInt1:=[1,3,5,7,9];
TInt2:=[2..5,8..10];

这样TInt1 就是由1、3、5、7、9 组成的集合,TInt2 就是由2、3、4、5、8、9、10 组成的集合。

 

关系运算,就是对集合类型的运算,遵循数学中关于集合运算的规则,运算的结果是布尔值。集合的关系运算就是判断两个集合相互之间的关系,关系运算符包括:=(等于)、<>(不等于)、>=(大于等于)、<=(小于等于)。
集合A 等于集合B,是指两个集合中的元素完全一样(不管元素的排列顺序如何),否则就是不相等,如下:

[1,2,3,4]=[2,4,1,3]
[1,2,3,4]<>[5,8,9]

如果集合B 中的元素在集合A 中都可以找到,那么称集合A 大于等于集合B,反之称集合B 大于等于集合A,如下:

[1,2,3,4]>=[1,2,3]

注意:Object Pascal 中不能用>或<对集合类型进行关系运算。因为集合类型不是有序类型,所以不能用Ord、Pred、Succ 等函数。

 

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]

复制代码procedure TForm4.Button8Click(Sender: TObject);
var
   SetEnum  :=  [one, Two];
begin
  if One in SetEnum then
  begin
    ShowMessage('Exclude函数执行失败');
  end
  else if Two in SetEnum then
  begin
    ShowMessage('SetEnum - [Two]执行失败');
  end
  else if not (Three in SetEnum) then
  begin
    ShowMessage('SetEnum + [Three]执行失败');
  end
  else if not (Four in SetEnum) then
  begin
    ShowMessage('Include函数执行失败');
  end

  else if not (ten in SetEnum) then
  begin
    ShowMessage('Include函数执行失败');
  end
  else
  begin
    ShowMessage('执行成功!');
  end;
end;



示例:
用随机函数产生20个互不相同的40到100的随机整数,然后按从小到大顺序打印。
解:按以下步骤处理:
①为使产生的随机整数互不相同。因此,每产生一个数,都要判断集合中已否包含,如果没有包含,就放到集合中,并统计个数,直到20个。
②将集合中的数移到数组中,此题利用下标序号从小到大的特征进行映射排序打印。
Pascal程序:
Program Exam511;
Uses  Crt ;
Var a: Array[40..100] Of boolean;
    dd: set Of 40..100;                {定义集合dd}
    n: Integer;
Procedure  Init;                     {定义产生并处理随机数的过程}
Var i,m: Integer;
Begin
  n:=0;dd:=[ ];                        {集合dd初值为空}
  repeat
      begin
        Randomize;                   {将随机发生器作初始化处理}
        m:=Random(100);                {产生随机整数m}
        if not (m in dd) and (m > 40 ) then
          begin
            dd:=dd+[m]; inc(n)         {把m放入集合dd中}
          end;
      end
  until n=20;
End;
Procedure Print;                      {定义打印过程}
Var i,j,k:Integer;
Begin
  fillchar(a,sizeof(a),false);        {将数组a的各元素置false值}
  For i:=40 To 100 Do
    if i in dd then a[ i ]:=true;    {以集合元素值为下标的数组元素赋真值}
  For i:=40 To 100 Do                  {以下标号为序(从小到大)输出}
    If a[ i ] Then  Write(i:4);      {输出a数组中元素值为真的下标号}
End;
Begin                                    {主程序}
  Clrscr;
  init;                              {产生随机数,并存入集合中}
  print;                             {打印}
  Repeat Until KeyPressed;
End.
posted @ 2018-10-14 21:57  北极星 - North Star  阅读(546)  评论(0编辑  收藏  举报