FORTRAN语言第7章(共8章).ppt_第1页
FORTRAN语言第7章(共8章).ppt_第2页
FORTRAN语言第7章(共8章).ppt_第3页
FORTRAN语言第7章(共8章).ppt_第4页
FORTRAN语言第7章(共8章).ppt_第5页
已阅读5页,还剩138页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

FOTRAN77/90程序设计,土木工程学院 2008.11,第一节 数组概念,第二节 数组的说明与引用,第三节 数组元素的存储结构,第四节 数组的输入输出,第五节 数组应用-程序举例,第七讲 数组,第一节 数组的概念,前面章节涉及的问题都是比较简单,编写的程序也不复杂,这些程序的一个突出特点是所处理的数据量非常少,采用的数据类型都是简单的内部数据类型,使用的变量都是普通变量。然而在实际的科研数值计算中,往往遇到的是一些涉及大量数据的复杂问题,如:,?思考:输入某班50个学生的成绩,统计平均成绩以及高于平均分学生的人数。 定义50个变量存放各个学生的成绩? 定义1个变量,循环读入各个学生的成绩,同时累计50个学生的总成绩,进而求出平均成绩; 当统计高于平均分学生人数时,再次输入50个成绩?,不合适,可以,不合适,解决方法:使用数组!,第一节 数组的概念,求解100元一次方程组。 求解高阶微分方程。 计算5050阶矩阵的转置矩阵。 对某班30名学生的学习成绩进行排序处理。 以上问题都要涉及几十、几百、几千,甚至上万个数据,如果在程序中采用简单的内部数据类型和变量来求解这类问题,其难度将大大增加,甚至无法设计和编写程序。,第一节 数组的概念,在输入数据时,用不同的名字引用每一个存储单元比较烦琐。如果有100个数需要处理,将需要一个长的输入语句,其中每个变量被列出一次。,第一节 数组的概念,简单变量是用来代表一个数据;而把具有相同类型的一批数据看成是一个整体,叫做数组。给数组取一个名字叫数组名,所以数组名代表一批数据,数组中的每一个数据称为数组元素,它可通过顺序号(下标)来区分。,一、变量与数组的区别,第一节 数组的概念,只要给出数组名和下标就可以表示某一数组元素。例如: 一个班30个学生的FORTRAN语言课程成绩组成一个数组G,每个学生的成绩可表示为: G(1),G(2),G(3),G(i),G(30),例:30个学生4门课程的成绩 S(1,1),S(1,2),S(1,3),S(1,4) S(2,1),S(2,2),S(2,3),S(2,4) S(30,1),S(30,2),S(30,3),S(30,4),在上例中,区分G数组的元素需要一个顺序号(下标),故称为一维数组;而区分S数组的元素需要两个顺序号,故称为二维数组,其中第一个下标代表元素所在行号,第二个下标为该元素所在列号。,一、变量与数组的区别,二、数组的分类,引入数组以后,让一批同类型数据共享一个名字,不必为每一对象都取一个名字。数组元素是按顺序号连续存放的,我们可以用循环语句控制下标的变化,这给在同一方式下处理多个同类型数据带来极大方便。例如:,第一节 数组的概念,REAL P(5),AVER !定义P数组 DO I=1,5 READ(*,*)P(I) !输入成绩并存入P数组 AVER=AVER+P(I) !求成绩之和 ENDDO AVER=AVER/5 !求平均成绩,一、数组说明的内容,第二节 数组的说明与引用,程序中所有数组都要先说明该数组的名字、类型、维数及大小,以便编译系统给数组分配相应的存储单元。 1)数组名:数组和变量一样,也用标识符来命名; 2)数组的类型:数组的类型由数组元素的类型来决定; 3)数组的维数:为了区分数组元素所需顺序号(下标)的个数; 4)数组的大小:数组中包含数组元素的个数,由数组每维下标的上界和下界来决定。,一、数组说明的内容,数组名、数组的维数和每一的上、下界的定义要用到数组说明符。其一般形式为: 数组名(维说明符 ,维说明符),维说明符的个数就是数组的维数。 维说明符至少1个,最多7个。,维说明符的一般形式为: 维下界: 维上界 维下界与维上界之间用“ :”分隔,下界为1时,可省略不写。维下界与维上界都只能是整型表达式。维界表达式的值必须是整数值,而且维上界的值必须大于维下界的值。,一、数组说明的内容,维说明符的一般形式为: 维下界: 维上界 在维界表达式中,允许出现整型常量、整型变量或者星号“ * ”。不允许出现函数或数组元素。 如果在维界表达式中出现整型变量名,则该数组称作可调数组。如果出现星号“ * ”,则只能用星号作为维的上界,这样的数组叫做假定大小的数组。 可调数组和假定大小数组只能出现在子程序,不允许在主程序中使用。,说明方法一:用DIMENSION说明数组 DIMENSION 数组说明符 ,数组说明符 例:DIMENSION A(1:5), B(-1:2),二、数组说明的方法,第二节 数组的说明与引用,注意:1)DIMENSION语句是非执行语句,必须放在程序单位的可执行语句之前; 2)用DIMENSION语句只说明了数组的名字、维数、大小等特性,但不能说明数组的数据类型。此时,数组类型的说明方法与变量名相同。 如无特别指明,数组的类型服从IN规则 用类型说明语句指明数组的类型,说明方法二:用类型说明语句说明数组 类型说明关键字 数组说明符,数组说明符 例: INTEGER A(1:5), B(-1:2),用类型说明语句可以直接说明数组的全部特性。,二、数组说明的方法,CHARACTER*8 NAME(30) REAL SCORE(5, 30) 说明了字符型数组NAME,数组元素的长度为8,还有实型数组SCORE。,说明方法三:同时使用DIMENSION和类型说明语句说明数组 其一般形式为:类型符,DIMENSION(维说明符):数组名 例:INTEGER , DIMENSION(1:5) : A, B(-1:2),C,DIMENSION属性统一说明大小,名字后个别说明大小 个别优于统一,REAL(4), DIMENSION(1:3,1:4) : D=0 上例中说明了三个整型一维数组A,B,C,一个二维实型数组D,其中A,C各含有5个元素,B含有4个元素;D中含有12个元素。 在说明数组时,可以在数组名后面给出维说明,这时以该数组名后的维说明为准。,二、数组说明的方法,DIMENSION A(1:5), B(-1:2),C(1:3,1:4) INTEGER A,B REAL C,三、数组元素的引用,数组元素是通过数组元素名来引用的。数组元素名的一般形式是,数组名(下标表达式,下标表达式) 其中:下标表达式为整型表达式,如果不是整型,则自动取整之后再使用;下标表达式的个数必须等于该数组的维数,每个下标表达式的值必须在相应的维下界到维上界之间。,第二节 数组的说明与引用,注意:1、数组元素表示数组中每个成份的值,数组元素名表示数组元素的名字。但在实际使用中,数组元素与数组元素名并不加区分。由于数组元素名是用数组名后面带下标表示的,所以数组元素名叫下标变量。下标变量可以和简单变量等同使用。,三、数组元素的引用,注意:2、数组元素名与数组说明符的区别 REAL A(3,3) S1=A(1,1)+A(1,2)+A(1,3) S2=A(2,1)+A(2,2)+A(2,3) S3=A(3,1)+A(3,2)+A(3,3),两个语句中都有A(3,3),由于它出现在两个不同类型的语句中,所以含义截然不同。REAL语句中的A(3,3)是数组说明符,其含义是定义了一个实型二维数组,有9个元素。赋值语句中A(3,3)是数组元素名。,三、数组元素的引用,注意:3、在F77中,除了在I/O语句中之外,其他场合不允许对数组进行整体操作,只能对数组的元素逐个进行操作。但在F90中,允许对数组进行整体操作。 REAL A(4,5) A(1:,:)=100.0 A(:,1:5:2)=470.0,是一个三元表达式,可作为数组元素 的下标表达式。其含义是从1变化到 5,每次增加2。三元表达式更一般的 形式如下:,下标三元组法:每一维是下标三元组e1:e2:e3或常量 例如二维数组:数组名(行三元组或常量,列三元组或常量) e1:起始下标值,缺省为下界d1 e2:终止下标值 ,缺省为上界d2 e3:步长值,缺省间隔为1,例:片段A(3:6)所含的元素为: A(3),A(4), A(5), A(6) 例: INTEGER,DIMENSION(6:50):A 则下列片段含有的元素为哪些? A(10:30:1) A(:20:5) A(8:10),第二节 数组的说明与引用,例:integer,dimension(11,6,4):B 片段B(6:11:2 , 5, 2:3)包含的元素为:,5为常量,B(6,5,2),B(6,5,3) B(8,5,2),B(8,5,3) B(10,5,2),B(10,5,3) 注意: 片段包含的元素不一定连续 片段将组成一个新的数组,第二节 数组的说明与引用,高级语言编译系统为一个数组分配一片连续的内存单元,每个存储单元存放一个数组元素。 对于一维数组按下标从小到大的顺序存放,第三节 数组元素的存储结构,INTEGER A(5),A(1),A(2),A(3),A(4),A(5),对于二维以上数组FORTRAN规定:数组元素在内存中是按列的顺序连续存放的。,INTEGER B(3,4),INTEGER B (3,4),A(1,1),A(2,1),A(3,1),A(1,2),A(2,2),A(3,2),A(1,4),A(2,4),A(3,4),第三节 数组元素的存储结构,在组织数组I/O时,对数组元素存储时的排列顺序要有清楚的了解。,第四节 数组的输入输出,一、使用DO循环输入输出数组元素,此方式的特点是:对于输入,每执行一个输入语句输入一个数组元素值;对于输出,每执行一个输出语句输出一个元素值。,将输入输出语句放在DO循环中,利用循环控制变量作为数组元素的下标来控制数组元素的输入或输出。,REAL A(4,5) DO I=1,4 DO J=1,5 READ(*,*) A(I,J) ENDDO ENDDO,每输入一个数要按一次回车键,A数组的20个数要输入20次。,第四节 数组的输入输出,一、使用DO循环输入输出数组元素,DO I=1,5 DO J=1,4 WRITE(*,*) A(J,I) ENDDO ENDDO END,A数组共输出20行,DO I1,100,2,WRITE(*,*) A(I),ENDDO, 用户可以自已控制输入和输出次序以及个数,DO K50,1,1,WRITE(*,*) M(K),ENDDO,把M数组的50个元素按逆序打印出来,将奇数(1, 3, , 99) 下标的元素输出,一、使用DO循环输入输出数组元素,DO I1,20,5,READ(*,*) A(I), A(I+1), A(I+2), A(I+3), A(I+4),这样每次循环一次则可输入5个数,每个数之间用逗号分隔。,ENDDO, 可以多设置一些输入项或输出项,例:,一、使用DO循环输入输出数组元素,第四节 数组的输入输出,二、以数组名作为输入输出项,这种方式是要对整个数组的所有元素进行输入输出操作,元素的个数和元素的操作次序都不能由自己控制,必须是对整个数组进行操作。,READ (*,*) X(1),X(2) ,X(3) ,X(4) ,X(10),WRITE (*,8) X(1),X(2) ,X(3) ,X(4) ,X(10),注:对于二维数组采用数组名方式进行输入和输出时,因为二维数组元素的存储是按列存放,所以,在输出时是按存储顺序来打印的。,例:,INTEGER Y(2,3),READ (*,*) Y,WRITE (*,7) Y,7 FORMAT (1X,3i8),END,假设Y数组的各元素值为:10 11 12,20 21 22,从键盘输入各元素的值为:10,20,11,21,12,22,执行打印语句的打印结果是,10 20 11,21 12 22,如果要打印出与数组的实际结构相符的结果,最好用隐DO方式,即:,WRITE(*,7) (Y(I,J),J=1,3),I=1,2),打印结果为:10 11 12,20 21 22,INTEGER,DIMENSION(3,3):A READ(*,*) A WRTIE(*,10) A 10 FORMAT(1X,3I5) END,第四节 数组的输入输出,二、以数组名作为输入输出项,数组元素按照它们在内存中的排列顺序输入输出。该方式要特别注意数据的组织。,当执行READ语句时,从键盘依次键入赋给A的数据就可以了,但输出A的数据时注意按“列”存储的原则,对二维以上数组要注意这个问题。比如从键盘输入:1,2,3,4,5,6,7,8,9,1 4 7 2 5 8 3 6 9,三、利用隐含DO循环控制数组元素的输入输出,隐DO循环只能用于输入和输出语句以及DATA语句中,它可以按要求来指定数组中需要输入或输出的部分,并且可以人为地规定输入或输出格式。,隐式DO循环实际上是一种带控制循环变量的DO循环,但简化成只有DO循环的第一句,并且把关键字DO隐去。隐式DO循环的一般形式如下: I = m1, m2, m3 其中,m1表示循环的初值;m2表示循环的终值;m3表示循环的增量。如果省略本项目,则默认为1。,隐式DO循环不是一种可以独立存在的语句。它只能作为输入输出列表的一个组成部分,用来控制重复读写的次数。它的应用形式如下: (I/O列表, 循环变量名 = 循环初值, 循环终值, 循环增值),也就是把I/O列表与循环控制部分一起用括号括起,中间用逗号分开,称为隐式DO循环列表,写在读写语句后面作为读写对象。,三、利用隐含DO循环控制数组元素的输入输出,WRITE(*,*)(A,B,N=1,5),WRITE(*,*)A,B, A,B, A,B, A,B, A,B,(1) 单重隐DO结构 (iotable,i=e1,e2 ,e3 ),当e31时,可省略,例:,INTEGER x(5),READ(*,*) (x(I),I1,5) READ(*,*) x(1), x(2), x(3), x(4) ,x(5),可将5个元素的值一次性输入,每个数之间用逗号分隔,也可以分若干次输入,WRITE(*,*) (x(I),I1,20) WRITE (*,*) x(1), x(2), x(20),将20个元素按标准格式输出,WRITE(*,*) (x(I),I1,5) WRITE(*,*) x(1), x(2), x(3), x(4) , x(5),输出X数组中的部分元素,WRITE(*,*) (x(I),I1,20,2) WRITE(*,*) x(1), x(3), x(19),有选择地输出X数组中的元素,注:当只需要给X数组中的前N个元素输入值时,可以写成 READ(*,*) N, (X(I),I1,N),但N不能放在隐含DO循环内,以下语句是错误的:READ(*,*) (N, X(I),I1,N),因为在进入循环之前,循环终值N必须有确定的值。,(2) 双重隐DO结构,(iotable,j=e1,e2,e3),I=p1,p2,p3),内层隐 DO循环,外层隐 DO循环,READ(*,*)( B(I,J),J1,3),I1,2),例:,相当于执行下面语句:,READ(*,*) B(1,1), B(1,2), B(1,3), B(2,1), B(2,2), B(2,3),输入数据时,你可以一次输入完毕,也可以分成若干次来输入,WRITE(*,*)( B(I,J),J1,3),I1,2),例:,输出数据时,打印成一行,也可用格式的方式,将其打印成二行,WRITE(*,10) (B(I,J), J=1,3),I=1,2),10 FORMAT (10X,3I6),READ(*,*)((A(I,J),J=1,3),I=1,2) 行在外按行序,一个READ语句一行输入:1,2,3,4,5,6 与外观一致的输入输出格式 READ(*,*)((A(I,J),J=1,3),I=1,2) 格式隐DO输入:1 2 3 4 5 6 DO I=1,2 READ(*,*)(A(I,J),J=1,3) ENDDO 行显DO列隐DO的输入:1,2,3 4,5,6,输入格式:一行输入,输入格式:与外观一致,第四节 数组的输入输出,要注意使用DO循环和隐DO循环在控制数组I/O时,在I/O格式上的差异。如:,第四节 数组的输入输出,WRITE(*,*) (A(I),I=2,14,3),DO I=2,14,3 WRITE(*,*) A(I) ENDDO,DO循环控制执行一次输出语句,就要输出一行(一条记录),且每行上仅有一个数组元素的值;而执行一次隐DO循环的输出语句,就把数组A的若干个元素同时输出到一行上,即它等价于WRITE(*,*) A(2), A(5), A(8), A(11), A(14)。,WRITE(*,(1X,F6.2) (A(I),I=2,14,3),例:编写程序,形成以下形式的二维数组。,分析:从数组元素的取值分析,元素的值与其下标值有一种对应关系。如果数组元素的两个下标用i、j表示,当ij时数组元素值为1;当ij时,数组元素值为i-j+1。,INTEGER A(5,5) DO I=1,5 DO J=1,5 IF(I=J)THEN A(I,J)=1 ELSE A(I,J)=I-J+1 ENDIF ENDDO ENDDO,WRITE(*,10) & (A(I,J), J=1,5),I=1,5) FORMAT(1x,5I6) END,A(I,J)=1 IF(ij)A(I,j)=I-J+1,第五节 给数组赋初值,DATA语句是专门给变量、数组和字符子串赋初值的,其一般格式为:,nlist:由变量名、数组名、数组元素名和字符子串组成. 名字之间以逗号(,) 分隔 clist:常数和符号常数组成. 整数数据项间以 , 分隔 每项数据与写上与无符号数字,代表说常数重复r次,nlist 与clist按从左到右的顺序一一对应。,变量表列,初值表,1格式:DATA nlist /clist/,nlist/clist/,3与赋值语句的区别,2功能 给变量、数组、数组元素和字符子串提供初值。,4例:,DATA I,R,D,C/1.2,0.3,3.0DO,(4.0,5.0)/ 等价于 DATA I/1/,R/2.0/,D/3.0DO/,C/(4.0,5.0)/ DATA I/1/ DATA R/2.0/ DATA D/3.0DO/ DATA C/(4.0,5.0)/,有S和K数组需赋初值,DIMENSION S(5),K(2,3),DATA S/1.2,2.3,3.0,4.5,2.8/,K/1,2,3,4,5,6/,DATA (S(I),I1,5)/1.2,2.3,3.0,4.5,2.8/,(K(I,J),J1,3),I1,2)/1,3,5, 2, 4, 6/,DATA S,K/1.2,2.3,3.0,4.5,2.8,1,2,3,4,5,6/,DIMENSION S(5),K(2,3),DIMENSION S(5),K(2,3),5注意:,(1) 变量表列中的变量与初值表中的常量在个数、类型等方面要一一对应。,例如,下列各DATA语句都是错误的: DATA A, B, C/2.0, 5.8/ DATA A, B, C/2.0, 5.6, 3.5, 10.0/ DATA I, K, X/3.6, 4.5, 4.5 /,初值表中的数据个数少于变量表列中变量的个数,初值表中的数据个数多于变量表列中变量的个数,变量表列中的前两个变量是整型,而初值表中的前两个常量为常数,即它们的类型不一致。,若K的初值是10,C的初值是“ FORTRAN 77”,A数组有4个元素,或DATA k,C,A/10, FOTRAN77,1.23,0.5,3.3,1.45/,(1) 变量表中变量的个数与对应的初值个数必须相同,(2) 变量的类型与初值的类型必须按顺序一一对应,(2) 在初值表中如果有n个连续的常量相同,则可以简写为: n常量,例如,DATA语句 REAL A(3,2),B DATA A,B/1.0, -1.0, 0.0, 0.0, -1.0, -1.0, -1.0/ 可以写成 DATA A, B/1.0, -1.0, 20.0, 3-1.0/,(20.0表示两个连续的0.0, 31.0也表示三个连续的1.0) 但特别要注意,31.0不能写成3(1.0),因为 3(1.0)是一个表达式。,若M数组有100个元素,它的前50个元素的初值为0,后50个元素的初值是1,表示如下:,DATA (M(I),I1,50)/50*0/,(M(I),I51,100)/50*1/,DIMENSION M (100),或者 DATA (M(I),I1,50),(M(I),I=51,100)/50*0 ,50*1/,或者 DATA M/50*0,50*1/,下列DATA语句都是错误的: DATA A, B, C, Y, Z/1.0, 1.0, 20.0, 2(1.0)/ 在此语句中,2(1.0),原意可能是表示两个连续的1.0,但实际上这是一个表达式; DATA X, Y, Z/1.0/3.0, 1.32.5, 4.01.234/ 在此语句中,初值表中出现了三个表达式1.0/3.0、 1.32.5与4.01.234。 正确写法是 DATA X, Y, Z/0.3333333, 3.25, 2.766/,(3) 在初值表中不允许出现任何形式的表达式。,例如,在一个程序单位中依次下三个DATA语句: DATA A, B, C, /1.0, 2.0, 3.0/ DATA K, S, B/10, 4.0, 5.0/ DATA A, K, B/2.4, 6, 10.0/ 其中变量A分别在第一和第三个DATA语句中赋了初值, 此时以第三个DATA语句中赋的初值为准,即变量A的最后初值为2.4。 同样的道理,变量K的最后初值为6,变量B的最后初值为10.0。,(4) 如果在一个程序单位中有多个DATA语句给同一变量初值,则以最后一个DATA语句中所赋的初值为准。,(5) FORTRAN77中DATA语句的作用是赋初值,它本身不是可执行语句。,系统在对FORTRAN77源程序进行编译的过程中就完成了这个赋初值的操作。并且,用DATA语句为变量赋初值后,在程序中还可以对赋过初值的变量重新赋值。,静态数组优点是存储分配算法简单,运行速度快,缺点是存储开销较大。 在元素个数不确定时,为考虑最坏情况,静态数组声明的很大,导致浪费。 动态数组优点是存储开销小,缺点是存储分配算法复杂,运行速度慢。 示例:统计学生成绩,人数不定。 PROGRAM example871 !使用静态数组程序 INTEGER score(100),i,j,n,x REAL : av,sum=0.0 WRITE(*,“(1X,请输入班级学生人数:,)”) READ*,n WRITE(*,“(1X,请输入,I3,名学生成绩:)”) n READ*,(score(i),i=1,n) DO i=1,n sum=sum+score(i) ENDDO av=sum/n WRITE(*,“(1X,该班学生平均成绩是:,F5.1)“) av END,第六节 动态数组,第六节 动态数组,PROGRAM example872 !使用动态数组程序 INTEGER,DIMENSION(:),ALLOCATABLE : score(:) INTEGER i,j,n,x REAL : av,sum=0.0 WRITE(*,“(1X,请输入班级学生人数:,)”) READ*,n ALLOCATE(score(n) WRITE(*,“(1X,请输入,I3,名学生成绩:)”) n READ*,(score(i),i=1,n) DO i=1,n sum=sum+score(i) ENDDO av=sum/n WRITE(*,“(1X,该班学生平均成绩是:,F5.1)“) av END PROGRAM,使用动态数组,需进行声明。声明时不指定大小。 一般格式: 类型声明符,DIMENSION(:,:),ALLOCATABLE:数组名,数组名 或者 类型声明符,ALLOCATABLE : 数组名(:,:),数组名(:,:) 示例: INTEGER,DIMENSION(:),ALLOCATABLE : num,score REAL,DIMENSION(:,:),ALLOCATABLE : A,B INTEGER,ALLOCATABLE : num(:),score(:) REAL,ALLOCATABLE : A(:,:),B(:,:),第六节 动态数组,动态数组声明后,使用ALLOCATE语句为分配存储空间,指定维下界和上界。 一般格式: ALLOCATE(数组名(维说明符),数组名(维说明符) ALLOCATE语句维说明符中的下界和上界可以是整型变量或整型表达式。 ALLOCATE语句中指定数组维数与声明的数组维数相同,否则产生语法错误。 ALLOCATE通过状态变量获得执行状态,若成功,则状态为0,否则为错误号。 示例: INTEGER,DIMENSION(:),ALLOCATABLE : num ! num为一维动态数组 REAL,DIMENSION(:,:),ALLOCATABLE : arr ! arr为二维动态数组 CHARACTER*10,ALLOCATABLE : book(:,:,:),name(:) !定义三维和一维动态数组 n=4; m=5; READ *,k ALLOCATE(num(5),arr(n,m),book(35,4,k),name(n+m+k) ALLOCATE(num(n),arr(-5:n,m:m+10),book(m,n,k) ALLOCATE(num(n),arr(-5:n,m:m+10),book(m,n,k) ALLOCATE(num(:n),arr(-5:n,m:m+10),book(m+1,n+2,k+3),STAT=ierr),为动态数组分配存储空间,8.7 动态数组/示例,例从键盘输入数目不确定的一批正整数,将这批整数保存在数组中,然后反序输出这批整数。分别采用静态数组和动态数组编写程序实现之。 !使用静态数组程序 PROGRAM static_array PARAMETER(max=200) INTEGER : i, n=0, array(max) READ *,i DO WHILE (i.NE.-1) n=n+1 array(n)=I READ *,i ENDDO PRINT *,data_number=,n PRINT *,(array(i),i=n,1,-1) END,第八章 数组及经用,!使用动态数组程序 PROGRAM dynamic_array INTEGER,ALLOCATABLE : array(:) INTEGER : i,n=0,m READ *, m ALLOCATE(array(m) READ *,i DO WHILE (i.NE.-1) n=n+1 array(n)=i READ *,i,ENDDO PRINT *,data_number=,n PRINT *,(array(i),i=n,1,-1) END,DEALLOCATE(ARRAY) END,例1 输入10个整数,并按输入时的逆序输出,每行5个数。,PROGRAM MAIN IMPLICIT NONE INTEGER,DIMENSION(10):A READ*,A WRITE(*,(5I3) A(10:1:-1) END 或WRITE(*, (5I3) (A(I),I=10,1,-1),一批数据的处理引入数组,程序结构: 单位定义 说明所有数组 输入数组 数组的处理 输出数组 END,第五节 数组的应用,苏州科技大学计算中心,第八章 数组及应用,输入数据:以行为主输入 12 个矩阵数据,每行输入一个数据: 12.5 23.8 54.2 78.9 92.4 45.3 0 24.4 84.2 32.8 72.8 43.2 输出结果:输出转置后数组: 12.5 92.4 84.2 23.8 45.3 32.8 54.2 0.0 72.8 78.9 24.4 43.2,第五节 数组的应用,使用隐含DO循环输入输出数组,苏州科技大学计算中心,第八章 数组及应用,输入数据:输入 5 名学生的成绩,每行输入多个成绩: 85,94,78,51,35 输入第奇数个学生新成绩: 11,33,55 输出结果: 5名学生的最新成绩是: 11.0, 94.0, 33.0, 51.0, 55.0 更新前平均成绩是: 68.60 更新后平均成绩是: 48.80,REAL A(0:9,0:9) DO I=0,9 DO J=0,9 A(i,j)=SQRT(10.*I+J) ENDDO ENDDO WRITE(*,10)(I,I=0,9) 10 FORMAT(7X,10(I1,6x) DO I=0,9 WRITE(*,20)I,(A(I,J),J=0,9) 20 FORMAT(1X,I1,2X,10(F5.3,2X) ENDDO END,按如下格式打印100以内整数的平方根表。,例计算N个测试数据的平均值和标准偏差。测试数据个数不定。 解:已知:N个测试数据data为:X1,X2,X3,Xn。从键盘输入。实型。 求:平均值Xa和标准偏差Xs。实型。 平均值计算公式为: Xa=(X1+X2+X3+Xn)/N 标准偏差计算公式为:Xs= 测试数据用一个一维数组X表示,平均值用变量Xa表示,标准偏差用变量Xs表示。测试数据个数不确定,假设最大个数max为50,实际个数为N。从键盘输入数据,数据以非数值字符为结束标志。 输入数据:25.32,18.35,44.78,57.39,85.2,A 输出结果:测试数据: 25.32 18.35 44.78 57.39 85.20 平均值 : 46.21 标准偏差: 26.74,例已知8个无序整数,将这组整数由小到大(或由大到小)排序。,解:已知:无序整数A,数组,用DATA语句赋初值。数据个数为N,假定N=8。 求:将一组无序整数A从小到大排序。 采用选择法排序。基本思想:从第1个数据起在N个待排序数据中选择一个最小数,将最小数与第1个数据交换,称该步为第1趟排序;在从第2个数据起在剩余的N-1个数据中选择一个次最小数,将次最小数与第2个数据交换,称该步为第2趟排序;依次类推,直到在从第N-1个数据起在剩余的2个数据中选择一个较小数,将较小数与第N-1个数据交换,称该步为第N-1趟排序,直至排序任务完成,得到一组有序数据。 排序前数据: 51 34 37 54 72 12 58 40 排序后数据: 12 34 37 40 51 54 58 72,排序过程示意如图所示。,a(1,1),a(1,2),.,a(1,p) . a(i,1),a(i,2),.,a(i,p) . a(m,1),a(m,2),.,a(m,p),b(1,1) b(1, j) b(1,n) b(2,1) b(2, j) b(2,n) . b(p,1) b(p, j) b(p,n),A矩阵(m*p),B矩阵(p*n),C(i, j)=a(i,1)*b(1, j)+a(i,2)*b(2, j)+a(i,p)*b(p, j),Sum=0 DO k = 1 , p A的列数或B的行数 Sum = Sum + a(i, k) * b(k, j) ENDDO c(i, j) = Sum,i,j,例 矩阵乘法:(矩阵A和B相乘时,A的列数应和B的行数相等.),Sum=0 DO k = 1 , p A的列数或B的行数 Sum = Sum + a(i, k) * b(k, j) ENDDO c(i, j) = Sum,DO i=1 , m DO j=1 , n,ENDDO ENDDO,a(1,1),a(1,2),.,a(1,p) . a(i,1),a(i,2),.,a(i,p) . a(m,1),a(m,2),.,a(m,p),b(1,1) b(1, j) b(1,n) b(2,1) b(2, j) b(2,n) . b(p,1) b(p, j) b(p,n),A矩阵(m*p),B矩阵(p*n),i,j,例 矩阵乘法:(矩阵A和B相乘时,A的列数应和B的行数相等.),杨辉三角形实际是由二项式(X+Y)n展开式各项的系数构成,第i行就是(X+Y)i展开式的各项系数。从右图可看出三角形中各元素的规律。除第一列和主对角线元素全为1外,其余元素是它的上行的前一列元素与上一行本列元素之和。如果将这些数看成一个10行10列的数组(上三角视为全零),i表示行,j表示列,则有,例:打印扬辉三角,1 1 1 2 1 1 3 3 1 1 4 6 4 1 ,INTEGER,DIMENSION(10,10): A DO I=1,10 A(I,I)=1 A(I,1)=1 ENDDO DO I=3,10 DO J=2,I-1 A(I,J)=A(I-1,J-1)+A(I-1,J) ENDDO ENDDO DO K=1,10 WRITE(*,(10I6))(A(K,J),J=1,K) ENDDO END,例:打印扬辉三角,1 1 1 2 1 1 3 3 1 1 4 6 4 1 ,注意打印格式,打印“魔幻方阵。魔幻方阵是指方阵的每一行、每一列、对角线元素之和均相等,其值为n(n2+1)/2,n代表方阵的行数和列数。一个n阶奇数方阵由1到n2个自然数构成。其组成规律是: (1)将1放在第1行的中间一列; (2)由1开始依次从左下到右上方向放连续数,如m放在A(i,j),则m+1放在A(i-1,j+1); (3)如果i-1n,则j+1为1; (5)如果A(i-1,j+1)已放数,则将数放在A(i+1,j)中。 以下是五阶魔幻方阵: 17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9,例:在一有序数列中,插入一数,使插 PARAMETER(N=30) 入后的数列仍然有序. INTEGER A(N) A 3 , 5 , 11, 22, 28, 56, 76, 88 READ*,N1 X=45 READ*,(A(I),I=1,N1) 第一步,先找插入的位置P READ*,X P=1 P=1 DO WHILE(X.GT.A(P).AND.P.LE.N1) DO WHILE(X.GT.A(P).AND.P.LE.N1) P=P+1 P=P+1 END DO END DO 第二步,完成插入 DO I=N1,P,-1 DO I=N1,P,-1 A(I+1)=A(I) A(I+1)=A(I) END DO; A(P)=X END DO N1=N1+1 A(P)=X N1=N1+1 PRINT*,(A(I),I=1,N1) END,例:求二维数组的鞍点,即该点在行上最小,列上最大。 求第I行最小元素的程序段为: Q=1 DO J=2,N IF(A(I,Q).GT.A(I,J)Q=J END DO 求第Q列最大元素的程序段为: P=1 DO K=2,M IF(A(P,Q).LT.A(K,Q)P=K END DO 如果P=I,说明元素A(P,Q)是鞍点,Subroutine sub(a,m,n,l) Logical :L=.FALSE. Real a(m,n) Integer p,q Do I=1,m Q=1 DO J=2,N IF(A(I,Q).GT.A(I,J)Q=J END DO P=1 DO K=2,M IF(A(P,Q).LT.A(K,Q)P=K END DO If(p.eq.I)then print*, p,q,是鞍点 L=.true. End do End Subroutine sub,例如:输入一个45的矩阵,求其鞍点 Parameter(m=4,n=5) Real,dimension(m:n):a Logical:L=.false. Read*,(a(I,j),j=1,5),I=1,4) !按行输入 Call sub(a,m,n,L) If(.not.L)print*,没有鞍点 end,例 1,第五节 数组的应用,选择排序法的原理很简单,步骤如下: 1)找出全部N个数据中最小的一个,把它和数列的第1个数字交换位置。 2)找出剩下N1个数据中最小的一个,把它和数列的第2个数字交换位置。 3)找出剩下N2个数据中最小的一个,把它和数列的第3个数字交换位置。 4),一直做到只剩下一个数据为止 。 下面以3 ,2, 5 ,1,4这组数字阐述选择排序法的排序过程:,例 1,第一轮扫描 3,2, 5,1,4,发现1最小,把它跟第1个数字交换位置,数据变成1,3,2, 5,4。,第二轮扫描 扫描的数据为剩下的3,2, 5,4,发现2最小,把它跟第2个数字交换位置,数据变成1,2,3,5,4。,第三轮扫描 扫描的数据为剩下的3,5,4,发现3最小,把它跟第3个数字交换位置,数据变成1,2,3,5,4。,第四轮扫描 扫描的数据为剩下的5,4,发现4最小,把它跟第4个数字交换位置,数据变成1,2,3,4,5。,PARAMETER(N=5) INTEGER A(N),TEMP DATA A/3,2,5,1,4/ DO I=1, N MIN=A(I) DO J=11, N IF(MINA(J)THEN TEMP=A(J) A(J)=A(I) A(I)=TEMP MIN=A(I) ENDIF ENDDO ENDDO PRINT*,A END,! 暂时令A(I)是最小值,! 发现A(I)不是最小,! 把A(I)、A(J) 这两个数值交换,例 1,第五节 数组的应用,冒泡排序法的步骤: 1)从第1个数字开始,依序把两个相邻的数值互相比较大小。如果前一个数字比后一个数字大,就把它们的位置互相交换。 2)一直做到每一对相邻的数字都比较过后才结束这一轮的工作。 3)回到第1步,再做下一循环的比较。如果有N个数字要排序,就需要重复N1次的扫描工作。 下面以3 ,2,5 ,1,4这组数字阐述冒泡排序的过程:,例 1,第一轮扫描:,经过第一轮扫描后,会找出最大的数值5,并把它放在数值的最后面。 第二轮扫描:,在第二轮扫描中,可以不去比较数列的最后一个数字,因为在第一轮中,就已经确定它是数列中的最大数值。如果硬是要比较的话,仍然可以排列出正确的结果,只不过会降低程序效率。在这一轮扫描中,可以找出数列的第2大数值,并且把它放在数列的倒数第2个位置上。,例 1,第三轮扫描:,这一轮中,不需再比较3,4的大小,因为在上一轮中,就已经确立了43的事实。因为4是数列中第2大的数字,而最大的数字又已经排在4的后面。同样地,在这一轮扫描中,确立了数列的第3大数值是3,并且把它安置在数列的倒数第3个位置上。 第四轮扫描:,虽然表面上看起来已经排序完毕,但是还是要经过这一轮的扫描后才能确定。因为在这次扫描后才会确定数列的第4大数值。而找出第4大数值后,因为总共只有5个数字,最小的数值也会跟着找出来,排序结束。 可以由上面的过程看到,冒泡排序法可以想像成是让重的东西向下沉,轻的东西向上浮。等到状态稳定,就会得到排序结果。,PARAMETER(N=5) INTEGER A(N),TEMP DATA A/3,2,5,1,4/ DO I=N-1, 1, -1 DO J=1, I IF(A(J)A(J+1)THEN TEMP=A(J) A(J)=A(J+1) A(J+1)=TEMP ENDIF ENDDO ENDDO PRINT*,A END,! 开始做N1次的扫描,! 一对一对的来比较,I之后的数字不用比较,! 如果A(J)A(J+1)就把这两个数值交换,例 1,49,38,65,97,13,76,27,49,第五节 数组的应用,49,38,65,97,13,76,27,49,例 1,38,49,65,97,13,76,27,49,例 1,38,49,65,97,13,76,27,49,例 1,38,49,65,97,13,76,27,49,例 1,38,49,65,97,13,76,27,49,例 1,38,49,65,76,13,97,27,49,例 1,38,49,65,76,13,97,27,49,例 1,38,49,65,76,97,13,27,49,例 1,38,49,65,76,97,13,27,49,例 1,38,49,65,76,27,13,97,49,例 1,38,49,65,76,27,13,97,49,例 1,38,49,65,76,27,13,49,97,例 1,38,49,65,76,27,13,49,97,例 1,DO j=1, n-1 if (a(j)a(j+1) then 交换 a(j),a(j+1) end if ENDDO,38,49,65,76,27,13,49,97,38,49,65,76,27,13,49,例 1,38,49,65,76,27,13,49,97,38,49,65,76,27,13,49,例 1,38,49,65,76,27,13,49,97,38,49,65,76,27,13,49,例 1,38,49,65,76,27,13,49,97,38,49,65,76,27,13,49,例 1,38,49,65,76,27,13,49,97,38,49,65,76,27,13,49,例 1,38,49,65,76,27,13,49,97,38,49,65,13,27,76,49,例 1,38,49,65,76,27,13,49,97,38,49,65,13,27,76,49,例 1,38,49,65,76,27,13,49,97,38,49,65,13,76,27,49,例 1,38,49,65,76,27,13,49,97,38,49,65,13,76,27,49,例 1,38,49,65,76,27,13,49,97,38,49,65,13,49,27,76,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论