480 likes | 616 Views
先看一题. 题目 : 输入 50 个学生的某门课程的成绩,打印平均分. A[1] A[2] A[3] A[4] A[5] A[59]A[60]. 引申. 题目 : 输入 50 个学生的某门课程的成绩,打印出低于平均分的 同学号数与成绩 ;.
E N D
先看一题 题目:输入50个学生的某门课程的成绩,打印平均分
A[1] A[2] A[3] A[4] A[5] A[59]A[60] 引申 题目:输入50个学生的某门课程的成绩,打印出低于平均分的同学号数与成绩; 分析:在解决这个问题时,虽然可以通过读入一个数就累加一个数的办法来求学生的总分,进而求出平均分。但因为只有读入最后一个学生的分数以后才能求得平均分,且要打印出低于平均分的同学,故必须把50个学生的成绩都保留下来, 然后逐个和平均分比较,把高于平均分的成绩打印出来。如果,用简单变量a1,a2,…,a50存放这些数据,可想而知程序要很长且繁。要想如数学中使用下标变量ai形式表示这50个数,则可以引入下标变量a[i]。这样问题的程序可写为:
这样问题的程序可写为: • tot:=0;{tot表示总分}for i:=1 to 50 do {循环读入每一个学生的成绩,并累加它到总分}beginread(a[i]);tot:=tot+a[i];end;ave:=tot/50;{计算平均分}for i:=1 to 50 doif a[i]<ave then writeln(‘No.’,i,‘ ’,a[i]);{如果第i个同学成绩小于平均分,则将输出} • 而要在程序中使用下标变量,则必须先说明这些下标变量的整体―数组,即数组是若干个同名(如上面的下标变量的名字都为a)下标变量的集合。
一维数组定义 在编程时用到一批类型相同的数据,为了处理上的方便,通常以数组的形式来定义这一批数据。 1:一维数组的定义: (1) type数组类型名=array [下标类型] of 数组元素类型;var变量名:数组类型名; 其中:a,b是这一批数据的名称,称为数组名;array、of是定义数组的保留字;中括号中的数字是数据编号的下限和上限,同时也说明了数据的个数(上限-下限);最后一个是数据的基类型,如integer,char,real,boolean。 type rowtype=array [1..100] of integer; var a,b:rowtype; arraytype为一个类型标识符,表示一个下标值可以是1到 8, 数组元素类型为整型的一维数组; 而a1,a2则是这种类型的数组变量。
第二种 一维数定义方式 其实我们可以,直接在var区中定义数组: var 数组名:array [下标类型] of 数组元素类型; 如上例: var a,b:array [1..100] of integer; 这样是不是方便很多哦! Price:array[1..20] of real; Mail:array[1..30] of boolean Score:array[60..100] of integer Number:array[‘a’..’z’] of integer 定义如下数组: 1、表示20种商品的价格 2、表示30件邮件的安全邮资情况 3、统计50个学生在一次考试中(满分100,最低分60)各分数的分布情况 4、统计一篇文章中各字母的出现频率(所有字母均小字)
判断下列数组定义是否正确 (1)Type atype=array[1..n] of real; ( ) (2)Type btype=array[10..5] of boolean; ( ) (3)Type ctype=array[1..5000)] of char; ( ) (4)Type dtype=array[1.0..10.0] of integer; ( ) (5)Type etype=array[1..’5’] of boolean; ( ) 1. √ 2. ×(10>5) 3. ×(sqr函数不能用) 4. ×(下标不能是实型) 5. ×(下标类型不一致,前面是整型,后面是字符型) 下标必须是有界的,可以是整形、字符型、布尔型……也应是有界的,上下标中是连续的,下标也可以是表达式,下标2的序号大于下标1的序号
说明部分定义了一个数组变量之后,pascal 编译程序为所定义的数组在内存空间开辟一串连续的存储单元。 • 如果将一个变量比做一个盒子,由数组是一批盒子,盒子的数量取决于数组定义的大小,每个盒子上都用数字1、2、3…标记 • 在使用大数据量的题目时,需要用到数组,使用数组的优点非常明显,省去定义大量变量的繁琐,而且可以任取数组的某一个下标的值,如取数组中第29个变量的值,则可以写成a[29],其是29就是数组a的下标。 用下标来指示数组中的元素 A[1] A[2] A[3] A[4] A[5] A[59]A[60]
PASCAL允许在定义数组的时候就给数组的每个元素赋值,但是必须放在常 量说明区中定义。但是与其他常量定义不同的是; 其他常量的定义一经定义就不能再修改,但是数组可以任意修改。它只是在 常量说明区中定义,但它的每一个元素相当于变量,可以到程序里再改变它的值。 数组赋初值的方法:两种 1、CONST A:ARRAY [1..5] OF INTEGER=(1,2,3,4,5); B:ARRAY [‘C’..’E’] OF INTEGER=(100,200,1000); 2、TYPE ARR=ARRAY[1..5] OF INTEGER; CONST A:ARR=(1,2,3,4,5); 注意:当括号内初值个数与数组元素个数不一致时都会报错!!
初始化数组 如定义var b:array [1..100] of byte; 初始化程序:for i:=1 to 100 do b[i]:=0; 还可以写成:fillchar(b,sizeof(b),0);fillchar是一个过程,参数b是数组名,sizeof(b)是一个函数,用来求数组b的大小;此过程表示将数组b全部清零。 注意不能使用b=0来对数组进行赋值,为什么呢?
数组的输入 • 1、下面是几个常用输入数组元素的例子: • for i:=1 to 10 do read(a[i]); • {——从键盘读入数组元素的值;最常用的方法} • for i:=1 to 10 do a[i]:=i; • {——数组元素a[1]到a[10]的值分别为1到10;数据赋初值} • for i:=1 to 10 do a[i]:=0; • {——数组元素清0;最常用的数据初始化的方法} • for i:=1 to 10 do a[i]:=random(100); • {——随机产生10个100以内的数,赋给各数组元素}
数组的输出 • FOR i:=1 TO n DO WRITE(a[i],' ');
数组的查找 数组中查找x,若有返回x的下标 find:=0; FOR i:=1 TO n DO IF a[i]=x THEN BEGIN find:=i; break; END; halt:退出程序。 exit:退出过程、函数。如果在主程序,则效果和halt一样。 break:跳出循环
数组的插入 在数组的p位置插入一个元素x FOR i:= n DOWNTO p DO a[i+1]:=a[i]; a[p]:=x; p 空位置n+1 …… ……
数组元素的删除 • 从数组中把下标为p的元素删除掉 • FOR i:=p TO n DO • a[i]:=a[i+1]; • n:=n-1; ……
例题1 • 将a数组中的第一个元素移到数组未尾,其余数据依次向前平移一个位置。 1 2 n-1 n …… 1 2 n-1 n ……
如果没有const 会如何? 用const有什么好处? 如果想移动方向相反如何改?(向右)
程序举例:输入十个人的成绩,然后算出平均分,显示低于平均分的成绩。程序举例:输入十个人的成绩,然后算出平均分,显示低于平均分的成绩。 PROGRAM JJZX(INPUT,OUTPUT); VAR A:ARRAY [1。。10] OF REAL; I:INTEGER; J:REAL; BEGIN J:=0; WRITELN(’输入成绩:‘); FOR I:=1 TO 10 DO BEGIN READLN(A[I]); J:=J+A[I] {求总分} END; J:=J/10; {求平均分} FOR I:=1 TO 10 DO IF A[I]<J THEN WRITELN(A[I]) END。
输入10 个整数,找出最小的数所在位置,并把此数与第一个数对调。 PROGRAM JJZX(INPUT,OUTPUT); VAR A:ARRAY [1。。10] OF INTEGER; J,K:INTEGER; BEGIN WRITELN(’输入数据:‘); FOR J:=1 TO 10 DO READLN(A[J]); K:=1; FOR J:=1 TO 10 DO IF A[J]〈A[K] THEN K:=J;{找出最小的数及所在位置K} J:=A[1]; A[J]:=A[K]; A[K]:=J; {把第一个数与最小的数对调位置} WRITELN(’最小的数是:‘,A[1],’它的位置是:‘,K) END。
编程:随便输入100个字母,请统计其中‘A’的个数,并把它全部变成‘B’再反编程:随便输入100个字母,请统计其中‘A’的个数,并把它全部变成‘B’再反 序输出。
PROGRAM JJZX(INPUT,OUTPUT); VAR A:ARRAY [1。。100] OF CHAR; I,J:INTEGER; BEGIN WRITELN(’输入字符:‘); J:=0; FOR I:=1 TO 100 DO BEGIN READLN(A[I]); IF A[I]=‘A’ THEN BEGIN J:=J+1; A[I]:=‘B’ END END; WRITELN(’A的总个数是:‘,J); FOR I:=100 DOWN TO 1 DO WRITELN(A[I[]) END。
排序算法 排序过程(升序_从小到大) • 例如下面对5个进行排序,这个五个数分别为829105。按选择排序方法,过程如下: • ① ② ③ ④ ⑤ • 初始数据 : 829105 第一次排序: 829105289105289105 289105 第二次排序: 2891052891052891052 5 9 10 8 • 第三次排序: 259108259 108 • 258 109 • 第四次排序: 258 10 9 • 258 9 10 在第I轮排序中使用A[I] 和从A[I+1]~A[N]进行比 较,如果比A[I]小则交换两个 数的值,这样一轮下来A[I] 就是第 I小的元素 大家可以想一想如果要求 从大到小的排列怎么做呢?
例题2:排序算法 输入十个正整数,把这十个数按由小到大的顺序排列 分析:要把十个数按从小到大顺序排列,则排完后,第一个数最小,第二个数次小,……。因此,我们第一步可将第一个数与其后的各个数依次比较,若发现,比它小的,则与之交换,比较结束后,则第一个数已是最小的数(选择出最小的)。同理,第二步,将第二个数与其后各个数再依次比较,又可得出次小的数。如此方法进行比较,最后一次,将第九个数与第十个数比较,以决定次大的数。于是十个数的顺序排列结束。
“选择排序”源程序如下 • program ex5_2;var a:array[1..10]of integer;i,j,t:integer;beginwriteln('Input 10 integers:');for i:=1 to 10 do read(a[i]);{读入10个初始数据}readln;for i:=1 to 9 do{进行9次排序}beginfor j:=i+1 to 10 do{将第i个数与其后所有数比较}if a[i]>a[j] then {若有比a[i]大,则与之交换}begint:=a[i];a[i]:=a[j];a[j]:=t;end;write(a[i]:5);end;end.
输入一串字符,以'?'结束,分别统计其中每个数字0,1,2,……9出现的次数 Inc(i)的意思是把i加1的值放到i中 Inc(a,b)的意思是把a+b的值放到a中 Dec则是减
约瑟夫问题。m个人围成一圈,从第一个人开始报数,数到n的人出圈。再由下一个人开始报数,数到n的人出圈,……输出依次出圈人的编号。m值预先选定,n值由键盘输入。约瑟夫问题。m个人围成一圈,从第一个人开始报数,数到n的人出圈。再由下一个人开始报数,数到n的人出圈,……输出依次出圈人的编号。m值预先选定,n值由键盘输入。 例:m=8,n=5 依次出圈的是5,2,8,7…… 设一个包括m个元素的数组,开始将数组的每个元素放1。从第一个元素开始,依次取数组元素相加,当其和为n时,输出该元素的下标(它即是应该出圈人的编号)。然后将该元素清0,和也清0。 再从下一个元素开始,依次取数组元素相加,当其和为n时,再输出该元素的下标,如此继续,直到输出m个值以后结束。 当某数组元素置0后,相加时将不起作用,相当于该人已经出圈,不再参加报数。 1 2 m …… 1 1 1 1 1 1 1 1 1
16个人,第n个出局,j记录下标,s为和 program ex7_9; const m=16; var a:array[1..m] of integer; n,s,i,j:integer; begin for i:=1 to m do a[i]:=1; {初始准备} read(n); j:=0; {输出m个出圈人编号} for i:=1 to m do begin s:=0; {计数清0} while s<n do{计数为n时结束} begin {处理下标} if j<m then j:=j+1 else j:=1; s:=s+a[j] {计数} end; write(j:3); {输出出圈人编号} a[j]:=0; {该元素清0} end; end. 记录和等于n(出局数)时的下标
题:一座山周围有10个洞,顺时针编号为1-10,一头狼一天捉到一只兔子,他突发奇想,要与兔子玩一下智力,于是它说,兔子可以躲在这10个洞的任何一个中,他顺时针找,每次进第4个(进过的不在计算内)如进了8次还没有找到兔子,以后就再不吃这只兔子,你帮兔子想一下,它应当躲在那个洞比较好?题:一座山周围有10个洞,顺时针编号为1-10,一头狼一天捉到一只兔子,他突发奇想,要与兔子玩一下智力,于是它说,兔子可以躲在这10个洞的任何一个中,他顺时针找,每次进第4个(进过的不在计算内)如进了8次还没有找到兔子,以后就再不吃这只兔子,你帮兔子想一下,它应当躲在那个洞比较好? 10 1 2
【思路2】利用数组存放n个人,数组下标等于他的编号,然后模拟报数过程,报到m时输出该位置的人编号,然后该位置的值清0,继续报数并判断是否为0,是0则跳过。直到n个人全部出列为止。【思路2】利用数组存放n个人,数组下标等于他的编号,然后模拟报数过程,报到m时输出该位置的人编号,然后该位置的值清0,继续报数并判断是否为0,是0则跳过。直到n个人全部出列为止。
Program yueshefu;Var a:array[1..100] of integer; n,m,i,j,p:integer;Begin write('Input n,m:'); readln(n,m); for i:=1 to n do a[i]:=i; p:=1; {p用于记录报数的位置} for i:=1 to n do begin j:=0; {j用于记录报到的人数} while j<m do begin if a[p]<>0 then j:=j+1; if p=n then p:=1 else p:=p+1; {处理边界情况} end; if p<>1 then begin write(a[p-1],' ');a[p-1]:=0;end {处理边界情况} else begin write(a[n],' ');a[n]:=0;end; end;end.
【思路3】建立一个循环数组,数组元素的每一个值保存的是它的下一个元素的编号,如果报到m后只要修改m前面的元素的编号为m后面的元素的编号,这样就跳过了第m个元素,如此下去直到n个人全部出列。【思路3】建立一个循环数组,数组元素的每一个值保存的是它的下一个元素的编号,如果报到m后只要修改m前面的元素的编号为m后面的元素的编号,这样就跳过了第m个元素,如此下去直到n个人全部出列。
作业 • 计算并输出S:= 其中xi的值为1,3,4,5……17,19 yi的值为21,22,23……29,30. • 从健盘输入若个数,将它们按照从小到大的顺序输出。
一维数组应用示例 例1:输入50个数,要求程序按输入时的逆序把这50个数打印出来。也就是说,请你按输入相反顺序打印这50个数。 分析:我们可定义一个数组a用以存放输入的50个数, 然后将数组a内容逆序输出。 源程序如下: program ex5_1;type arr=array[1..50]of integer; {说明一数组类型arr}var a:arr;i:integer;beginwriteln('Enter 50 integer:');for i:=1 to 50 do read(a[i]);{从键盘上输入50个整数}readln;for i:=50 downto 1 do {逆序输出这50个数}write(a[i]:10);end.
题一 题目:输入50个学生的某门课程的成绩,打印出低于平均分的同学号数与成绩;
题二 • (1)输入一个不大于32767的正整数N,将它转换成一个二进制数。 算法:除2取余,反序输出 例如:输入:100输出: 1100100
排序算法 例2 输入十个正整数,把这十个数按由小到大的顺序排列 分析:要把十个数按从小到大顺序排列,则排完后,第一个数最小,第二个数次小,……。因此,我们第一步可将第一个数与其后的各个数依次比较,若发现,比它小的,则与之交换,比较结束后,则第一个数已是最小的数(选择出最小的)。同理,第二步,将第二个数与其后各个数再依次比较,又可得出次小的数。如此方法进行比较,最后一次,将第九个数与第十个数比较,以决定次大的数。于是十个数的顺序排列结束。
排序过程(降序) • 例如下面对5个进行排序,这个五个数分别为829105。按选择排序方法,过程如下: 初始数据 :829105 第一次排序:829105928105102895102895 第二次排序:108295109285109285 第三次排序:109825109825 第四次排序:109852 在第I轮排序中使用A[I] 和从A[I+1]~A[N]进行比 较不过A[I]小则交换两个 数的值,这样一轮下来A[I] 就是第 I大的元素 大家可以想一想如果要求 从小到大的排列怎么做呢?
“选择排序”源程序如下 • program ex5_2;var a:array[1..10]of integer;i,j,t:integer;beginwriteln('Input 10 integers:');for i:=1 to 10 do read(a[i]);{读入10个初始数据}readln;for i:=1 to 9 do{进行9次排序}beginfor j:=i+1 to 10 do{将第i个数与其后所有数比较}if a[i]<a[j] then {若有比a[i]大,则与之交换}begint:=a[i];a[i]:=a[j];a[j]:=t;end;write(a[i]:5);end;end. • 请各位同学独自完成十个数据的升序的程序!
9、2、1 二维数组 一、二维数组的定义: 定义与一维数组类似, 但二维数组的定义有两个下标类型,且共有三种方法: 1、在TYPE中先定义,再到VAR中定义,例如: TYPE TABLE1=ARRAY [1。。4,1。。5] OF INTEGER; TABLE2=ARRAY [1。。4,’A’。。’E’] OF INTEGER; VAR A,B:TABLE1; C,D:TABLE2;
2、直接在VAR中定义(推荐使用本方法),例如:2、直接在VAR中定义(推荐使用本方法),例如: VAR A,B:ARRAY [1。。4,1。。5] OF INTEGER; C,D:ARRAY [1。。4,’A’。。’E’] OF INTEGER; 3、VAR中定义,但书写格式有点区别,例如: VAR A,B:ARRAY [1。。4] OF ARRAY [1。。5] OF INTEGER; C,D:ARRAY [1。。4] OF ARRAY [’A’。。’E’] OF INTEGER;
二、二维数组的存储结构: 例如有下面的定义: VAR A:ARRAY [1。。4,1。。5] OF INTEGER; 它相当于定义了一个矩阵,数组中的元素相互关系如下: A[1,1], A[1,2], A[1,3], A[1,4], A[1,5] A[2,1], A[2,2], A[2,3], A[2,4], A[2,5] A[3,1], A[3,2], A[3,3], A[3,4], A[3,5] A[4,1], A[4,2], A[4,3], A[4,4], A[4,5] 由以上看出,下标中第一个下标定义的是行的变化范围,第二个定义的是列的 变化范围,数组中总的元素个数=行 * 列。比如A数组就有20个,A[3,2]表示的是 第三行第二列的那个元素。
上面只是讲了二维数组各元素关系示意图,在内存中又是怎么存储的呢?上面只是讲了二维数组各元素关系示意图,在内存中又是怎么存储的呢? 因为内存是一个一维的空间,好象是一个数轴,只有X轴,没有Y轴,前面的示意图 是一个平面的图,既有X轴(行),又有Y(列)轴。但在计算机中存储的时候是按 行来存储的,即先存完第一行的元素,然后接着在后面存储第二行的元素…… 如下图所示: A[1,1] …… A[1,5] …… A[2,1] …… A[2,5] A[3,1] …… A[3,5] …… A[4,1] …… A[4,5] 知道这样的定义后,二维数组中的某一个元素就可以有两种的引用方法,一是 两个下标,如A[3,2],另外一种是单下标,像一维数组那样,但必须要确定这个元素在内存中的位置,如A[3,2]排在第10,则A[10]就是A[3,2]。 A[4,2]呢?
三、二维数组元素的引用: 方法与一维数组一样,也是数组名加下标,不过二维有两个下标: 数组名[下标1,下标2] 看看一个简单的程序: 输入4个学生的5门课成绩(思想是一行放一名学生的成绩,一行有5个元素, 分别存放5门课的成绩,总共有4行。) VAR A:ARRAY [1。。4,1。。5] OF REAL; I,J:INTEGER; BEGIN FOR I:=1 TO 4 DO FOR J:=1 TO 5 DO READ(A[I,J])
再看一个简单程序: 输入4名学生5门课程的成绩,然后以每个人一行的方式输出: VAR A:ARRAY [1。。4,1。。5] OF REAL; I, J:INTEGER; BEGIN FOR I:=1 TO 4 DO FOR J:=1 TO 5 DO READ(A[I,J]);{ 输入成绩} FOR I:=1 TO 4 DO BEGIN FOR J:=1 TO 5 DO WRITE(A[I,J]; WRITELN; END 为什么要WRITELN?
再看这个程序:输入4个学生5门课的成绩,然后输出每个学生的平均分。再看这个程序:输入4个学生5门课的成绩,然后输出每个学生的平均分。 VAR A:ARRAY[1。。4,1。。5] OF REAL; B:ARRAY [1。。4] OF REAL;{B数组用来放平均成绩} I,J:INTEGER; T:REAL;{T用来存放一个学生的总分} BEGIN FOR I:=1 TO 4 DO FOR J:=1 TO 5 DO READ(A[I,J]);{ 输入成绩} FOR I:= 1 TO 4 DO BEGIN T:=0; FOR J:=1 TO 5 DO T:=T+A[I,J]; B[I]:=T/5 END; FOR I:=1 TO WRITELN(B[I])
课堂练习:输入任意一个4*4的二维数组,找出每行最大的数,输出其数和位置,课堂练习:输入任意一个4*4的二维数组,找出每行最大的数,输出其数和位置, 也就是位于几行几列。 VAR A:ARRAY[1。。4,1。。4] OF REAL; I,J,K:INTEGER; BEGIN FOR I:=1 TO 4 DO FOR J:=1 TO 4 DO READ(A[I,J]);{ 输入数据} FOR I:=1 TO 4 DO BEGIN K:=1; FOR J;=2 TO 4 DO IF A[I,J]>A[I,K] THEN K:=J; {找出最大数的位置} WRITELN(’第‘,I,’行最大的数是:‘,A[I,K],’位于:‘,K,’列‘) END