pascal第5章数组.ppt
《pascal第5章数组.ppt》由会员分享,可在线阅读,更多相关《pascal第5章数组.ppt(49页珍藏版)》请在三一办公上搜索。
1、第五章 数组,第一节 一维数组第二节 二维数组第三节 字符数组和字符串类型,第一节 一维数组,为什么要使用数组,通过前面几章的学习,我们已经可以编写程序来解决各种相当复杂的问题了,但是当需要处理的数据比较多时,仅依靠前面的知识是不够的,即使简单的问题也可能需要比较复杂的程序来处理。请看下面的例子:例题 输入50个学生的某门课程的成绩,打印出低于平均分的学生序号与成绩。【分析】在解决这个问题时,虽然可以通过一个变量来累加读入的50个成绩求出学生的总分,进而求出平均分。但因为只有读入最后一个学生的分数后才能求得平均分,并且要求打印出低于平均分的学生序号和成绩,故必须把50个学生的成绩都保留起来,然
2、后逐个和平均分比较,把低于平均分的成绩打印出来。如果,用简单变量a1,a2,,a50存储这些数据,要用50个变量保存输入的数据,程序片断如下:readln(a1,a2,a10);readln(a41,a42,a50)注意,如果真正要像上面这样编写程序,则上面的所有省略号必须用完整的语句写出来。可以看出,这样的程序是多么繁琐。如果说处理的数据规模达到成千上万,上面的例子单单读入就会异常复杂,电脑的特点没有得到体现。,从以上的讨论可以看出,如果只使用简单变量处理大量数据,就必须使用大量只能单独处理的变量,即使是简单问题也需要编写冗长的程序。选手们可能已经看出,我们需要把一大批具有相同性质的数据组合
3、成一个新类型的变量,可以用简单的程序(比如循环50次)对这个新变量的各个分量进行相同的处理,每个分量仍然保留单个变量的所有性质(在上面的例子中,各分量是整型变量或实型变量的性质)。如果能象数学中使用下标变量ai形式表示这50个数,则问题就容易实现。在Pascal语言中,具有下标性质的数据类型是数组。如果使用数组,上面的问题就变得十分简单、清晰。例如,读入50个学生的成绩,只需写如下语句即可:for i:=1 to 50 doreadln(ai);,在这里引用了带下标的变量(分量变量称为数组元素)ai来代替a1,a2,a50,方括号中的i称为下标,当循环变量i=1时ai就是a1;当i=2时ai就
4、是a2;当i=50时ai就是a50。输入的时候,让i从1变化到50,循环体内输入语句中的ai也就分别代表了a1,a2,a50这50个带下标的变量。这样上述问题的程序可写为:tot:=0;/tot存储50个学生的总分for i:=1 to 50 do/循环读入每一个学生的成绩,并把它累加到总分中beginread(ai);tot:=tot+ai;end;ave:=tot/50;/计算平均分for i:=1 to 50 doif aiave then writeln(No.,i,ai);/如果第i个同学成绩小于平均分,则将输出这个学生的序号和成绩。要在程序中使用下标变量,必须先说明这些下标变量的整
5、体数组,即数组是若干个同名(如上面的下标变量的名字都为a)下标变量的集合,这些变量的类型全部一致。,一维数组,当数组中每个元素只带有一个下标时,我们称这样的数组为一维数组。,一维数组的定义,(1)类型定义类型定义一般格式为:type=;其中type是Pascal保留字,表示开始一个类型定义段。在其后可以定义若干个自定义的数据类型。是为定义的类型取的名字,称它为类型标识符。类型定义后,也就确定了该类型数据取值的范围,以及数据所能执行的运算。和Pascal提供的标准类型如integer、real等没什么区别。,(2)一维数组类型的定义一维数组类型的一般格式:var数组名:array下标1.下标2
6、of;对于上例:a:array 1.50 of integer;,说明:其中array和of是Pascal保留字。下标1和下标2 是同一顺序类型,且下标2的序号大于下标1的序号。它给出了数组中每个元素(下标变量)允许使用的下标类型,也决定了数组中元素的个数。基类型是指数组元素的类型,它可以是任何类型,同一个数组中的元素全部具有相同类型。因此我们可以说,数组是由固定数量的相同类型的元素组成的。再次提醒注意:类型和变量是两个不同概念,不能混淆。就数组而言,程序的执行部分使用的不是数组类型而是数组变量。数组的另一种定义形式,先定义数组的类型标识符,再定义数组,如:type array1=array1
7、.8of integer;var a1,a2:array1;其中array1为一个类型标识符,表示一个下标值从1到 8,数组元素类型为整型的一维数组;而a1,a2则是这种类型的数组变量,代表二个数组。我们平时更多的是将二者全并起来,直接定义:var a1,a2:array1.8of integer;,当在说明部分定义了一个数组变量之后,Pascal 编译程序为所定义的数组在内存空间开辟一串连续的存储单元。例如:var a:array 1.10 of integer;以下表示a数组在内存的存储如表所示:,a数组共有10个元素组成,在内存中10个数组元素共占10个连续的存储单元。a数组最小下标为1
8、,最大下标10。按定义a数组所有元素都是整型变量。,一维数组元素的赋值操作,数组元素的引用形式为:数组名下标表达式。数组一经定义后,数组元素就具有简单变量一样的性质,使用时必须写出下标。对于一维数组变量的赋值有两种形式:一是对各数组元素赋值,二是对数组所有元素整体赋值。例如:设有下列变量定义var a1,a2:array1.20 of integer;i:integer;执行下列语句:for i:=1 to 20 do a1i:=1;/数组元素赋值a2:=a1;/两个数组只要结构(元素个数和类型)相 同,就可以整体赋值 这个程序片段的功能是将一维整型数组变量a1、a2的所有数组元素都初始化赋值
9、为1,前面的循环语句是逐个赋值,最后一个赋值语句是两个一维数组间的整体赋值,其作用相当于把数组a1中每一个数组元素的值分别赋给数组a2中相应的元素,这要求两个数组具有相同类型和一样的下标范围。,一维数组的引用,一维数组元素的输入 不能整个数组输入,只能逐个元素赋值 ai:=x;一般用FOR循环做。如:For i:=1 to 7 do read(a i);一维数组元素的输出 不能整个数组一起输出,只能逐个元素输出 Write(a i);一般用FOR循环做。如:For i:=1 to 7 do write(ai);,例5.1 输入10个数,要求程序按输入时的逆序把这10个数打印出来。也就是说,按输
10、入相反顺序打印这10个数。【分析】我们可定义一个数组a用以存放输入的50个数,然后将数组a中的内容逆序输出。program ex5_1;type arr=array1.10of integer;/说明一数组类型arrvar a:arr;i:integer;begin writeln(Enter 10 integer:);for i:=1 to 10 do read(ai);/从键盘上输入10个整数 readln;/读入时起换行作用 for i:=10 downto 1 do/逆序输出这10个数 write(ai:10);end.,例5.2 输入一串字符,以?结束,统计其中每个字母出现的次数。【
11、分析】为了简单起见,只考虑每个小写字母出现的次数。为记录每个字母出现的次数,定义一个由26个元素组成的数组,下标类型是字符,元素类型为整型。如:num:arraya.z of integer;用numa记录字母a出现的次数,用numb记录字母b出现的次数,开始应将num的每个元素置成0,其实所有变量的初始值都为0。当读入的字符不是?时,应判断它是否为字母,若是则应将相应字母计数加1。此时需判断哪个字母,只要将读入的字母作为下标,就可以找出相应的数组元素,将它加1即可。若读入的字符是?则结束循环,最后输出统计结果。,程序如下:Program ex5_2;var num:arraya.z of i
12、nteger;ch:char;begin for ch:=a to z do/等价于fillchar(num,sizeof(num),0);numch:=0;read(ch);while ch?do begin if(ch=a)and(ch0 then wrtieln(ch,numch);end.,运行结果cabc*&8796abcaa?a4b2c3,例5.3 将a数组中第一个元素移到最后数组末尾,其余数据依次往前平移一个位置。【分析】为完成题目所要求的操作,其算法应该包括以下几个主要步骤:把第一个元素的值取出放在一个临时单元 temp中;通过 a2a1,a3a2,a4a3,anan-1,实现
13、其余元素前移 将 temp值送入an.Program ex5_3;const n=10;var a:array1.n of integer;i:integer;temp:integer;begin writeln(read,n,datas);for i:=1 to n do read(ai);temp:=a1;for i:=1 to n-1 do ai:=ai+1;an:=temp;writeln(Result:);for i:=1 to n do write(ai:3);end.,运行结果:read 10 datas:1 2 3 4 5 6 7 8 9 10 Result:2 3 4 5 6
14、 7 8 9 10 1,例5.4 宾馆里有一百个房间,从1-100编了号。第一个服务员把所有的房间门都打开了,第二个服务员把所有编号是2的倍数的房间“相反处理”,第三个服务员把所有编号是3的倍数的房间作“相反处理”,以后每个服务员都是如此。当第100个服务员来过后,哪几扇门是打开的。(所谓“相反处理”是:原来开着的门关上,原来关上的门打开。)【分析】此题较简单,只要设置一个表示门是开的还是关的标志数组,只有二种状态采用布尔型更直观。由于有固定的循环次数,用for循环显得简练。程序如下:Program ex5_4;const n=100;var a:array1.nof Boolean;i,j,
15、k:integer;begin for i:=1 to n do ai:=true;/可用fillchar(a,sizeof(a),true)代替 for i:=2 to n do for j:=1 to n do if j mod i=0 then aj:=not(aj);for j:=1 to n do if aj=true then write(j:5);/可写成:if aj then write(j:5);readlnend.运行结果:14 9 16 25 36 49 81 100,例5.5 约瑟夫问题:N个人围成一圈,从第一个人开始报数,数到M的人出圈;再由下一个人开始报数,数到M的
16、人出圈;输出依次出圈的人的编号。N,M由键盘输入。【分析】(1)由于对于每个人只有出圈和没有圈两种状态,因此可以用布尔型标志数组存储游戏过程中每个人的状态。不妨用TRUE表示出圈,FALSE表示没有圈。(2)开始的时候,给标志数组赋初值为FALSE,即全部在圈内。(3)模拟报数游戏的过程,直到所有的人出圈为止。,程序如下:Program ex5_5;var n,m,s,f,t:integer;a:array1.100 of boolean;/根据题意开出数组大小begin readln(n,m);/共n人,报到m出圈 for t:=1 to n do at:=false;f:=0;t:=0;s
17、:=0;/刚开始所有变量默认值也是0 repeat t:=t+1;/逐个枚举圈中的所有位置 if t=n+1 then t:=1;/数组模拟环状,最后一个与第一个相连 if at=false then s:=s+1;/第t个位置上有人则报数 if s=m then/当前报的数是m begin s:=0;/计数器清零 write(t,);/输出出圈人的编号 at:=true;/此处的人已出圈,设置为空 f:=f+1;/出圈的人数增加一个 end;until f=n;/直到所有的人都出圈为止end.,运行结果:输入:8 5 输出:5 2 8 7 1 4 6 3,例5.6 输入十个正整数,把这十个数
18、按由大到小的顺序排列。(选择排序)将数据按一定顺序排列称为排序,排序的算法有很多,其中选择排序是一种较简单的方法。【分析】要把十个数按从大到小顺序排列,则排完后,第一个数最大,第二个数次大,。因此,我们第一步可将第一个数与其后的各个数依次比较,若发现,比它大的,则与之交换,比较结束后,则第一个数已是最大的数(最大的泡往上冒)。同理,第二步,将第二个数与其后各个数再依次比较,又可得出次大的数。如此方法进行比较,最后一次,将第九个数与第十个数比较,以决定次大的数。于是十个数的顺序排列结束。如对5个进行排序,这个五个数分别为829105。按选择排序方法,过程如下:初始数据:829105第一次排序:8
19、29105928105102895102895第二次排序:108295109285109285第三次排序:109825109825第四次排序:109852对于十个数,则排序要进行9次。,程序如下:program ex5_6;var a:array1.10of integer;i,j,t:integer;begin writeln(Input 10 integers:);for i:=1 to 10 do read(ai);/读入10个初始数据 readln;for i:=1 to 9 do/进行9次排序 begin for j:=i+1 to 10 do/将第i个数与其后所有数比较 if ai
20、aj then/若有比ai大,则与之交换 begin t:=ai;ai:=aj;aj:=t;end end;for i:=1 to 10 do write(ai:5);end.运行结果:输入:8 67 52 189 74 5 58 9 23 41输出:5 8 9 23 41 52 54 67 74 189,例5.7 编程输入十个正整数,然后自动按从大到小的顺序输出。(冒泡排序)【分析】用循环把十个数输入到A数组中;从A1到A10,相邻的两个数两两相比较,即:A1与A2比,A2与A3比,A9与A10比。只需知道两个数中的前面那元素的标号,就能进行与后一个序号元素(相邻数)比较,可写成通用形式A
21、i 与A i+1比较,那么,比较的次数又可用1(n-i)循环进行控制(即循环次数与两两相比较时前面那个元素序号有关);在每次的比较中,若较大的数在后面,就把前后两个对换,把较大的数调到前面,否则不需调换位置。下面例举5个数来说明两两相比较和交换位置的具体情形:5 6 4 3 7 5和6比较,交换位置,排成下行的顺序;6 5 4 3 7 5和4比较,不交换,维持同样的顺序;6 5 4 3 7 4和3比较,不交换,顺序不变 6 5 4 3 7 3和7比较,交换位置,排成下行的顺序;6 5 4 7 3 经过(1(5-1)次比较后,将3调到了末尾。经过第一轮的1(N-1)次比较,就能把十个数中的最小数
22、调到最末尾位置,第二轮比较1(N-2)次进行同样处理,又把这一轮所比较的“最小数”调到所比较范围的“最末尾”位置;每进行一轮两两比较后,其下一轮的比较范围就减少一个。最后一轮仅有一次比较。在比较过程中,每次都有一个“最小数”往下“掉”,用这种方法排列顺序,常被称之为“冒泡法”排序。,程序如下:Program ex5_7;const N=10;var a:array1.N of integer;/定义数组 i,j,t:integer;begin for i:=1 to N do Readln(a i)/输入十个数 for j:=1 to N-1 do/冒泡法排序 for i:=1 to N-j
23、do/两两相比较 if a i ai+1 then/比较与交换 begin t:=ai;ai:=ai+1;ai+1:=t;end;for i:=1 to N do/输出排序后的十个数 write(a i:6);readlnend.运行结果:输入:2 5 8 6 12 34 65 22 16 55输出:2 5 6 8 12 16 22 34 55 65,例5.8 用筛法求出100以内的全部素数,并按每行五个数显示。【分析】把2到100的自然数放入a2到a100中(所放入的数与下标号相同);在数组元素中,以下标为序,按顺序找到未曾找过的最小素数minp,和它的位置p(即下标号);从p+1开始,把凡
24、是能被minp整除的各元素值从a数组中划去(筛掉),也就是给该元素值置 0;让p=p+1,重复执行第、步骤,直到minpTrunc(sqrt(N)为止;打印输出a数组中留下来、未被筛掉的各元素值,并按每行五个数显示。用筛法求素数的过程示意如下(图中用下划线作删去标志):2 3 4 5 6 7 8 9 10 11 12 13 14 1598 99 100/置数 2 3 4 5 6 7 8 9 10 11 12 13 14 1598 99 100/筛去被2整除的数 2 3 4 5 6 7 8 9 10 11 12 13 14 1598 99 100/筛去被3整除的数 2 3 4 5 6 7 8 9
25、 10 11 12 13 14 1598 99 100/筛去被整除的数,程序如下:Program ex5_8;const N=100;Var a:array1.n of boolean;i,j:integer;Begin Fillchar(a,sizeof(a),true);a1:=False;for i:=2 to Trunc(sqrt(N)do if aI then for j:=2 to N div I do ai*j:=False;t:=0;for i:=2 to N do if ai then Begin write(i:5);inc(t);if t mod 5=0 then wri
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- pascal 数组
链接地址:https://www.31ppt.com/p-6513751.html