还剩8页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
§6集合及记录类型1集合类型
1.1集合类型的定义集合是同类型对象的一个汇合,它是指同类型对象汇合在一起构成的数据结构集合的每一个对象称为集合的元素集合元素必需是有序简洁数据类型,集合元素的类型称为集合的基类型集合的一般形式为TYPE〈类型标识符=setof〈基类型);基类型可以是整型、字符型、布尔型、枚举型、子界型等,但不能是实型或结构类型例如TYPEletter=setofA..Z;varchich2:letter;也可以干脆写成varchich2:setof,A.Z;在Pascal中集合是用一组括在方括号中的元素来表示,元素之间用逗号分隔如:[ABCD]是四个枚举量的集合[
1..20]表示1到20的全部整数的集合
[0]是单元素集[]表示空集一个集合类型变量的取值,可以是基类型中全部元素按不同的组合而构成的子集例如,上面说明变量chi的・・2]全集B,Q,]任一子集..CX,..2]]单元素集空集空集及全部的集合类型都兼容
1.2集合类型的运算chi:4[A..C]];是合法的集合赋值对集合除可以进行赋值运算外,还可以进行以下运算交(*)运算两集合之交S1*S2为一集合,所得元素由SI、S2中相同的元素组成如[
0..7]*[
0..4]二[
0..4]并(+)运算两集合之并S1+S2为一集合,所得元素由SKS2中全部相同的元素组成如[
0..7]+[
0..4]二[
0.・7]
[01]+
[146]=
[0146]差(-)运算两集合之差S1-S2为一集合,所得元素由只存在于S1而不在S2的那些元素组成如[
0..7]-[
0..4]=[
5..7]•比较运算集合可进行“
二、=、“二”、◊”等比较运算等于j”——S1=S2若S1及S2中全部元素均相同,结果为true否则为false如[
0..4]=[
0..4]结果为true[
0..7]=[
0..4]结果为false不等于“〈”一一S1OS2S1及S2中至少有一个元素不同,如[
0..7][
0..4]结果为true[
0..4][
0..4]结果为false包含“=”——S1=S2表示S2是S1的子集被包含“〈二”一一S1=S2表示S1是S2的子集如[
0..7]〉二[
0.・4]结果为true
0..4]结果为false结果为true•检查in运算用来检查某一元素是否属于某一集合如:结果为true结果为false.Z]结果为true§
6.
1.3集合类型的表达式集合表达式是由集合常数、集合变量、集合构造符和集合运算符组成如k:=5;ch2-
[1234]+[k];运行之后,ch2中就会有5个元素
1、
2、
3、
4、5o留意[L.5]及
[12345]两种表达式是等价的集合运算相当快,在程序中常用集合表达式来描述困难的测试例如,条件表达式ch=Torch=uorch=Rorch=B可用集合表达式表示为chin[TURE]又如ifch=20andch=50then〈语句〉可写成ifchin[
20..50]then〈语句〉§
6.
1.4留意问题集合类型是一种运用简洁,节约内存而又运算速度快的数据类型,在解决某些问题时,它能使程序编写简明清楚,节约内存而又节约运行时间但是运用集合时必需留意以下几点
①Pascal规定集合的元素个数不超过256个当实际问题所需的元素个数大于256时,可采纳布尔数组代替集合类型所以vari:setofinteger;的说明是错误的,因为它的元素个数超过256个
②集合类型变量不能进行算术运算,也不允许用读/写语句干脆输入/输出集合所以集合的建立要通过赋值语句实现,或先初始化一个集合,然后通过并+运算向集合中逐步加入各个元素;集合的输出也必需间接地转换,如集合中的元素是数字或字母,可通过序数值的转换关系输出对应的字符
③集合的元素是无序的,所以ordpred和succ函数不能用于集合类型的变量【例1】用集合方法编程,实现把100以内的全部素数找出来,然后把求得的每十个素数排成一行,形成素数表算法分析用筛法求素数第一步,定义一个集合类型,如sss它包含99个元素,从2到100;其次步,定义两个集合变量,如筛集合s和素数集合p它们是sss类型的变量;第三步,按筛法找出全部素数;第四步,间接输出素数表算法求精如下
①把2到100逐步放入筛中,建立筛集合s;
②选定筛中最小的素数一一2;
③把选定的素数放入素数集合P中;
④检查筛集合s从中删去选定素数和它的全部倍数;
⑤重复步骤
2、
3、4直到筛集合s变成空集,素数集合P完全建立;
⑥间接输出集合P中的元素,且每10个一行程序清单programerato;constn=100;typesss=setof
2..n;varsp:sss;nextj:integer;Begins:=[
2..n];{初始打算}P=[];next:=2;repeat{建立素数表}whilenotnextinsdonext:=next+l;p:=p+[next];j:=next;whilej=ndobegin{去掉选定素数的倍数}s:=s-[j];j:=j+next;end;{whileuntils=[];j=0;fornext:=2tondo{输出素数集合元素}ifnextinpthenbeginwritenext:5;j=j+1;ifj=10then{每10个素数为一行}beginwritein;j=0;end;end;{if}End.§
6.2记录类型记录类型数据是由固定数量,具有不同类型的成份组成这种数据在实际问题中常遇到,如描述学生姓名、性别、年龄、班级和各科成果的档案登记表这种数据用数组类型是特别烦琐的,可以利用Pascal供应的记录类型§
6.
2.1记录类型的数据记录是由固定数量的字段又称域的元素所组成的一种结构,各个字段可以具有各种不同的数据类型,每个字段都有一个名称即字段标识符记录类型定义的一般形式TYPE〈类型标识符》二RECORD〈字段名1:〈类型1;IIIIII〈字段名n:类型n;END;记录中描述对象的字段表,包括了记录的固定部分和变体部分;记录的固定部分由字段名和类型说明部分,记录的变体部分在本节的最终介绍下面介绍如何描述记录的数据,例如typedate=recordyear:
1900..2500;month:JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC;day:
1..31;end;vardateldate2:date;对记录类型变量的访问,不同于数组那样通过下标来访问其成份,而是通过记录变量名,句号,字段名来访问记录中的成份,称为记录的点记法,其形式为〈记录变量名》.〈字段名》:=<数据项》;例如datel.year:=1937;datel.month:=JUL;datel.day:-1;假如记录的某个字段是字符型数组,如studentname字段是一个由20字符组成的字符型数组,则可用循环语句读入字符fori:=1to20doreadstudent.name[i];•记录类型及数组类型相像,允许在同类型的两个记录之间进行整体赋值如date2:=datel;•记录可以嵌套,即记录中的字段的类型也可以是记录,嵌套的记录类型是有层次的数据类型在同一层的标识符不能同名,但不同层的字段名可以同名例如varr:integer;s:recordr:real;s:recordr:char;s:boolean;end;end;对于层次记录的引用必需采纳自顶向下的完全路径,如varworker=recordage:
15..70;birth:recordyear:
1900..2200;month:
1..12;end;end;引用记录变量worker的域,表示诞生年,应写成worker.birth.year【例2】设学生成果登记表有下列项目学号、姓名、年龄、班级、数学、物理、政治、英语、总分现对学生成果进行统计,算出各科的总分和平均分程序清单programstu;constn=60;typestudent=recordno:integer;name:string
[16];age:
6..30;class:string
[8];mathphysicspoliticsenglish:
0..100;tai:
0..400;end;varst:array[
1..n]ofstudent;ijsummsumphsumplsume:integer;Beginfori:=1tondobeginreadlnst[i].nost[i].name;readlnst[i].agest[i].class;readlnst[i].mathst[i].physicsst[i].politicsst[i].english;st[i].tai:=st[i].math+st[i].physics+st[i].politics+st[i].english;end;summ:=0;sumph:=0;sumpl:=0;sume:=0;fori:=1tondobeginsumm:=summ+st[i].math;sumph:=sumph+st[i].physics;sumpl:=sumpl+st[i].politics;sume:=sume+st[i].english;end;writeinmath’summ,averagesumm/n;writeinphysicssumphaverageJsumph/n;writeinpoliticssumplaverageJsumpl/n;writeinenglishsumeaverageJsume/n;End.§
6.
2.2with语句从上例中可见,用点记法引用记录会使句子冗长,若能像存取简洁变量一样存取记录的字段,则会使之简便得多开域语句正好供应了这种功能,它“打开一个记录”后便可像引用变量那样运用字段名开域语句的一般形式为with〈记录变量名》do〈语句〉;其中do后面的语句可以是简洁语句,也可以是复合语句,在这些语句中,只要运用字段名就可以,不必再在前面写上记录变量名例如,给记录datel赋值,不用前面的点记法,而用开域语句,则为withdateldobeginyear:=1937;month:=Jul;day:=7;end;[例3]下面是用with语句对例2的改写programstu;Beginfori:=1tondowithst[i]dobeginreadInnoname;readlnageclass;readlnmathphysicspoliticsenglish;tai:=math+physics+politics+english;end;summ:=0;sumph:=0;sumpl:=0;sume:=0;fori:=ltondowithst[i]dobeginsumm:=summ+math;sumph:=sumph+physics;sumpl:=sumpl+politics;sume:=sume+english;end;writeinCmathsummaveragesumm/n;writeinJphysicssumphaverageJsumph/n;writeinpoliticssumplaverageJsumpl/n;writeinJenglishsumeaverageJsume/n;End.§
6.
2.3变体记录上面介绍的记录的元素,其数量和类型都是固定的,但在很多数据处理问题中,有时希望元素的数量及其类型能有所不同例如在学生档案中,政治面目这一栏,每个学生的状况可能不同,如共产党员填入党年份,共青团员填入团年份,一般学生什么都不用填记录的变体部分的一般形式TYPE〈类型标识符》二RECORD〈字段名1:〈类型1;IIIIII〈字段名n:类型n;CASE〈标记字段》〈类型标识符》OF〈标号1〈字段表1;IIIIII〈标号n:〈字段表n»;ENI;其中每个变体由一个标号表和一个字段表构成标号表是一个标号和用逗号分隔的标号序列,这些标号都是标记字段的值一个记录变量将选中哪一个变体是由变体部分中标记字段的值确定的,当标记字段的值只能是枚举型、字符型等有序类型的常量等于某一变体的标号时,则这个变体被选中访问记录变量变体部分的一个元素类似于访问固定部分中的一个元素例如TYPESTATUS=PMDS;PERSON=RECORDname:string
[20];sex:char;casepolitics:STATUSofP:pdate:
1900..2500;M:mdate:
1900..2500;S:;END;varp:PERSON;则可进行赋值p.name:=zhuming;p.politics:*;p.date:=1999;运用变体记录要留意以下几点
①标记字段的类型是有序类型,其标识符必需预先定义过;记录的固定部分必需放在变体部分之前;变体部分的case不同于一般的case语句,不需end匹配【例4】编制一个关于某科研小组成员年龄、学位状况的程序,进行处理和输出解因为学位状况困难,可能无学位,也可能是学士、硕士或博士,假如是博士还要考虑获得学位的时间、地点;假如是硕士和学士,要填入获得学位的时间程序清单programdeg;typedegree=dmqn;techer=recordi:integer;age:
20..70;casestatus:degreeofd:yearl:
1900..2500;state:string
[100];m:year2:
1900..2500;d:year3:
1900..2500;n:;end;vars:teacher;ch:char;k:integer;beginwrigtelninputagedegreedateocation:;fork:=lto100dowithsdobegini:二k;readlnage;readlnch;casechof’d status:二d;m:status:=m;q:status:=q;n:status:=n;end;{case}casestatusofd:beginreadlnyearlstate;writeini:5age:6yearl:7state;end;m:beginreadlnyear2;writeini:5age:6year2:7;end;q:beginreadlnyear3;writeini:5age:6year3:7;end;n:writeini:5age:6other;end;{case}end;{with}练习六
1.下列哪组类型的变量可以作为for循环中的循环限制变量().摸球嬉戏已知黑盒中的球为红、黄、蓝、白、黑五种颜色,从黑盒中依次取出三个球,若这三个球颜色互不相同,则可获奖恳求出取三种颜色的球的全部可能取法(用枚举类型).从键盘读入一个字符,推断若为数字,则输出“digits”;若为小写字符,则输出lower-letter;若为大写字符,则输出“upper-letterv;若为其它字符,则输出uspecialcharacters(用子界类型作为case语句标号).从键盘读入年、月、日,输出该日期是当年的第儿天(用子界类型).下列表达式中运算结果为true的是()A.
[246]
[642]B.
[1234]=[
1..4]C.7in
[2468]D.
[246]+
[246]=
[224466].下列有关集合运算的表达式中,有语法错误的是()A.Yin[CDK..Z]B.
[246]*
[852]C.[M飞]+
[369]D.[
1..100][
1..211].用集合类型实现筛法求质数.某小组(10人)的计算机成果格式如下姓名|性别|平常成果|期中成果|期末成果|总评成果其中总评成果=平常成果X20%+期中成果X30%+期末成果义50%假设你为小组长,编程完成下列功能输入学生的成果表,其中总评成果由程序算出按总评成果从高到低打印学生名单.指出下列类型定义中的错误TYPErec『RECORDcasekind:realof1:color:redbluegreen;5:p:Boolean;x:integer;ENDTPYErec2=RECORDname:string
[20];sex:malefemale;casei:
1..3of:math:integer;:phys:integer;:english:integer;END;
11.设有说明TYPEdate=RECORDyear:
0..9999;month:
1..12;day:
1..31END;pers=REC0RDname:array[
1..16]ofchar;birthdate:date;sem:malefemale;END;VARaa:pers;下列操作中错误的是readaa.birthdateyear;withaadoReadbirthdateyear;withaa.birthdatedoReadbirthdateyear;withaa.birthdatedoReadyear;
12.平面上的点由笛卡儿直角坐标系给出,建立描述平面上一点位置的数据类型,并编一个过程,求随意三点构成的三角形的外接圆输入xlylx2y2x3y3输出x0yOR(x
0、yO为圆心坐标,R为圆的半径)。