1
2009-7-29
第 9章 数 组
§ 1 数组的说明和数组元素的引用
§ 2 数组的逻辑结构和存储结构
§ 3 数组的输入和输出
§ 4 给数组赋初值
§ 5 程序举例
2
在日常计算中,经常会遇到一组类型相同数据的计算问题,如计算某班 35名同学某门课的平均成绩。
按之前所学,只能把程序编写为:
read(*,*) f1,f2,……,f35
f=(f1+f2+…+f35)/35.0
print*,f
end
缺点:代码效率低,不实用。
为了方便这种类型的计算,FORTRAN规定了一种“带下标”的 特殊变量,可以把 35个成绩值存入这种特殊变量中,以方便程序编写。
3
2009-7-29
f1
F(1 )
f2
F(2 )
f35
F(35 )
……
……
其中,F(1),F(2),……F(35) 即“带下标”的特殊变量。
称 F是一个 数组,而 F(1),F(2),……F(35) 为数组 F的 35个 数组元素 。
数组属于一种构造数据类型 (基本数据类型组合而成 )。
每个数组代表一组具有同一类型的变量;数组中所包含的变量称为数组元素;通过下标的变化指定元素。
对如前的计算问题,用数组编写要方便得多。
4
2009-7-29
dimension f(1:35)
read(*,*) f
sf=0.0
do 10 k=1,35
sf=sf+f(k)
10 continue
print*,sf/35.0
end
定义了一个一维数组给数组的 35个元素输入数据。
累加计算显示结果对于大批量的数据,可使用事先整理好的数据文件。
k 是变化的下标
5
2009-7-29
一、数组的说明 (定义 )
用 类型说明语句 或 dimension语句定义数组。
其一般形式为:
§ 1 数组的说明和数组元素的引用 (p195-197)
类型说明 (或 dimension) 数组名 (下标下界,下标上界,下标下界,下标上界,… )
第 1维的维说明符第 2维的维说明符
§ 1 数组的说明和数组元素的引用
6
2009-7-29
1,用类型语句定义数组如:
⑴ 数组名后 一对小括号 中包含的是维说明符,多个维说明符时用逗号隔开。
具有一个维说明符的数组为一维数组,具有两个维说明符的数组为二维数组,… 。通常我们 将二维及二维以上的数组称为多维数组 。
⑵ 每个维说明符规定了本维中下标的下界和上界,下界和上界之间用冒号隔开 。
⑶ 下标下界和上界必须是整型常量或整型常量表达式,
且 上界 ≥下界 。
real ia(1:10),w(1:3,1:2)
integer a(0:2,0:1,0:3)
§ 1 数组的说明和数组元素的引用
7
2009-7-29
如:
⑷ 当下标下界为 1时可以省略不写。
⑸ 数组定义 (包括变量定义 )必须放在可执行语句之前。
如:
parameter (low=1,ihig=9)
real ia(low,ihig+1)
integer n
read(*,*) n
real ia(1,n)
real ia(1:10),w(1:3,1:2)
§ 1 数组的说明和数组元素的引用
real ia(10),w(3,2)
不允许定义可变长度的数组。
x=1.0
real ia(1,10)
×
×
8
2009-7-29
2,用 dimension语句定义数组如:
⑴ 若仅有 dimension语句,数组的类型根据数组名首字母的隐式 I-N规则确定。
⑵ 显式类型说明,由 dimension语句与类型说明语句配合进行(由 dimension语句定义数组,由类型说明语句对数组名的类型进行显式说明)。
如:
dimension ia(1:10),w(1:3,1:2),a(0:2,0:1,0:3)
dimension ia(1:10),w(1:3,1:2),a(0:2,0:1,0:3)
integer a
real ia,w
§ 1 数组的说明和数组元素的引用
9
2009-7-29
二、数组元素的引用数组元素使用的一般形式:
数组名 (下标 1,下标 2…)
如:
⑴ 标准 Fortran77中,除了在输入和输出语句中外,其它场合不允许对数组进行整体操作,只能对数组元素逐个进行操作 。
integer a(10)
do 10,i=1,10
a(i)=0.0
10 continue
§ 1 数组的说明和数组元素的引用
10
2009-7-29
⑵ 数组元素的下标允许是任意算术表达式,如果表达式的类型为非整型时则自动取整。
⑶ 数组元素的下标值必须落在该维的上界和下界之内,即满足,下界 ≤下标 ≤上界 。
对于下标越界,大部分 Fortran系统在编译和连接时都不会报错,程序都会执行,但其结果会有问题。因此,对于数组运算,尤其是采用循环时,
对于下标的范围要注意控制。
§ 1 数组的说明和数组元素的引用
11
2009-7-29
一、一维数组的逻辑结构和存储结构
1,逻辑结构一维数组是线性表的一种表现形式 。
线性表的特点,⑴ 存在唯一的一个被称做“第一个”
的数据元素; ⑵ 存在唯一的一个被称做“最后一个”的数据元素; ⑶ 除第一个之外,表中的每个数据元素均只有一个前驱; ⑷ 除最后一个之外,表中的每个数据元素均只有一个后继。
一维数组的逻辑结构是 按数组元素下标值由小到大排列的一个线性表,每个元素的下标值确定了该元素在表中的位置。
§ 2 数组的逻辑结构和存储结构 (p198-200)
§ 2 数组的逻辑结构和存储结构
12
2009-7-29
2,存储结构一维数组在计算机内存中 占用一串连续的存储单元,
每个元素在内存中的存放顺序与逻辑结构是一致的。
如:
§ 2 数组的逻辑结构和存储结构
real ia(10)
ia(1)
ia(2)
ia(3)
ia(4)
ia(5)
ia(6)
ia(7)
ia(8)
ia(9)
ia(10)
13
2009-7-29
二、二维数组的逻辑结构和存储结构
1,逻辑结构可以看成是一个矩阵,每个元素的第 1个下标表示元素在矩阵中的行号,第 2个下标表示元素在矩阵中的列号。
如:
2,存储结构在内存中占有连续的存储单元 (存储单元是一维的 )。
二维数组在内存中 按列存放,先存放第 1列的元素,再存放第 2列的元素,依此类推,…… 。
real w(3,2) w(1,1) w(1,2) w(2,1) w(2,2)
w(3,1) w(3,2)
§ 2 数组的逻辑结构和存储结构
14
2009-7-29
如:
逻辑结构:
三、三维数组的逻辑结构和存储结构逻辑结构,可以看成是由多个二维矩阵 (或若干页表格 )
组成的。每个元素的第 3个下标表示元素所在的 页号,第
1个下标表示元素在该页表格的 行号,第 2个下标表示元素在该页表格的 列号 。(教材 p200例子)
存储结构,也占有一串连续的存储单元,依次存放各二维矩阵 (或各表格 )的所有元素 (按列存放 ) 。可以认为
“第1下标变化最快,中间次之,最后的下标变化最慢”
real w(3,2)
w(1,1) w(1,2)
w(2,1) w(2,2)
w(3,1) w(3,2)
存储结构,w(1,1)
w(2,1)
w(3,1)
w(1,2)
w(2,2)
w(3,2)
§ 2 数组的逻辑结构和存储结构
15
2009-7-29
注意:
存储结构,一个数组在计算机内存中实际存放的形式。
Fortran程序可以在一个输入 / 输出语句中通过数组名对所有数组元素进行一次性的输入 / 输出;
采用这种形式时,输入 / 输出的顺序是和存储结构的顺序一致的。
§ 2 数组的逻辑结构和存储结构
dimension c(2,2,2),问 c的元素存储顺序如何?
c(1,1,1) c(2,1,1) c(1,2,1) c(2,2,1) c(1,1,2) c(2,1,2)
c(1,2,2) c(2,2,2)
16
2009-7-29
Fortran中数组的输入输出有三种形式:
利用 do循环对数组进行输入输出
在输入输出语句中用数组名输入输出整个数组
在输入输出语句中使用 隐 do循环一、利用 do循环对数组进行输入输出如:
§ 3 数组的输入和输出 (p200-204)
integer a(10)
do 10 i=1,10
read(*,*)a(i)
10 continue
do 10 i=1,10
write(*,*)a(i)
10 continue
§ 3 数组的输入和输出
17
2009-7-29
如:
注,⑴ 在一个输入语句输入数据时,只有在回车后,输入的数据才会被该 read语句中的变量接收。
在通过键盘输入数据时,数据输入的形式是( ):
A,一次输入 10个数,然后回车。
B,每次输入 1个数,然后回车;共输入十次。
C,无所谓,每次输入几个数都行,都可以回车;如果不够 10个,后面接着输入。
integer a(10)
do 10 i=1,10
read(*,*)a(i)
10 continue
§ 3 数组的输入和输出
B
18
2009-7-29
注,⑴ 在一个输入语句输入数据时,只有在回车后,输入的数据才会被该 read语句中的变量接收。
⑵ 在一个输入语句输入数据时,若回车时输入的数据个数 > 该输入语句中的变量个数,则多余的数据作废。
⑶ 在一个输入语句输入数据时,若回车时输入的数据个数 < 该输入语句中的变量个数,则 read语句会继续等待输入数据,直到输入数据的个数足够为止。
如:
§ 3 数组的输入和输出
integer a(10)
read(*,*)a(1),a(2),a(3),…,a(10)
A,一次输入 10个数,然后回车。
C,无所谓,每次输入几个数都行,都可以回车;如果不够 10个,后面接着输入。
19
2009-7-29
integer a(10)
do 10 i=1,10
write(*,*)a(i)
10 continue
相当于有 10个 write(*,*)语句。
输出结果,每行输出 1个数组元素的值,共输出 10行。
integer a(10)
do 10 i=1,10,2
write(*,100)a(i)
10 continue
100 format(1x,2I4)
相当于有 5个格式输出语句,
每个格式输出语句对应一个输出记录。
输出结果,输出数组 a中下标为奇数的 5个数组元素,每行输出 1个元素,共输出 5行。
§ 3 数组的输入和输出
20
2009-7-29
如:
real w(3,2)
do 10 i=1,3
do 20 j=1,2
read(*,*) w(i,j)
20 continue
10 continue
§ 3 数组的输入和输出
read(*,*) w(1,1)
read(*,*) w(1,2)
read(*,*) w(2,1)
read(*,*) w(2,2)
read(*,*) w(3,1)
read(*,*) w(3,2)
输入形式:
每次输入 1个数,然后回车;共输入 6次。
21
2009-7-29
※,使用 do循环对数组进行输入输出,方法的 缺点:
效率低,一个输入 /输出语句只能输入 /输出一个数据。
real w(3,2)
do 10 i=1,2
do 20 j=1,3
write(*,100)w( j,i)
100 format(1x,2f6.2)
20 continue
10 continue
§ 3 数组的输入和输出
write(*,100) w(1,1)
write(*,100) w(2,1)
write(*,100) w(3,1)
write(*,100) w(1,2)
write(*,100) w(2,2)
write(*,100) w(3,2)
100 format(1x,2f6.2)
输出结果:
按列输出,每行输出 1个数组元素的值,共输出 6行。
22
2009-7-29
二、在输入输出语句中用数组名输入输出整个数组当在输入 /输出语句中仅使用数组名时,相当于 对数组的全部元素按在内存中的排列顺序进行输入 /输出 。
如,integer a(10)
read(*,*) a
write(*,100) a
100 format(1x,2I4)
read(*,*)a(1),a(2),a(3),a(4),a(5),a(6),a(7),a(8),a(9),a(10)
write(*,100)a(1),a(2),a(3),a(4),a(5),a(6),a(7),a(8),a(9),a(10)
100 format(1x,2I4 / 1x,2I4 / 1x,2I4 / 1x,2I4 / 1x,2I4)
§ 3 数组的输入和输出输出结果:
每行输出两个数组元素,共输出
5行。
23
2009-7-29
real w(3,2)
read(*,*) w
如:
read(*,*)w(1,1),w(2,1),w(3,1),w(1,2),w(2,2),w(3,2)
write(*,100) w
100 format(1x,2f6.2)
write(*,100)w(1,1),w(2,1),w(3,1),w(1,2),w(2,2),w(3,2)
100 format(1x,2f6.2 / 1x,2f6.2 / 1x,2f6.2)
输入时,输入的数据按列赋给数组中的各元素。
输出结果,w(1,1) w(2,1)
w(3,1) w(1,2)
w(2,2) w(3,2)
§ 3 数组的输入和输出
3
3 3 )
w(1,1) w(2,1) w(3,1)
w(1,2) w(2,2) w(3,2)
24
2009-7-29
※,使用数组名输入输出整个数组”方法的 缺点:
一个输入 /输出语句可以输入 /输出数组的全部数组元素;
但 无法控制输入 /输出元素的顺序,也无法控制输入 /输出元素的个数 。
三、在输入输出语句中使用隐含 do循环指把 do循环放在输入输出语句中,这种 do循环也称为隐 do循环 或 隐含 do循环 。
优点:
能控制在一个输入 /输出语句中输入 /输出多个数组元素 (全部或部分数组元素 )。
也能控制输入 /输出数组元素的顺序。
数组的输入 /输出推荐使用该方法。
§ 3 数组的输入和输出
25
书写方式,
2重隐循环,((输入输出元素,v=e1,e2,e3),u=f1,f2,f3)
3重隐循环,
(((输入输出元素,v=e1,e2,e3),u=f1,f2,f3),w=g1,g2,g3)))
1重隐循环,(输入输出元素,v=e1,e2,e3)
隐循环体 循环控制隐循环体 内循环控制 外循环控制
隐循环 作用,由循环控制列出隐循环体中的元素 。一般置于输入输出语句和 DATA语句中。
§ 3 数组的输入和输出
26
2009-7-29
integer a(10)
read(*,*) (a(i),i=1,10)
如,i是隐循环变量,初值为 1,
终值为 10,步长为 1。
隐 do循环外面必须加一对小括号。
read(*,*)a(1),a(2),a(3),…,a(9),a(10)
write(*,100) (a(i),i=1,10)
100 format(1x,5f6.2)
a(1) a(2) a(3) a(4) a(5)
a(6) a(7) a(8) a(9) a(10)
write(*,100) (a(i),i=1,10,2)
100 format(1x,5f6.2) a(1) a(3) a(5) a(7) a(9)
write(*,100) (a(i),i=10,1,-2)
100 format(1x,5f6.2) a(10) a(8) a(6) a(4) a(2)
§ 3 数组的输入和输出
27
2009-7-29
real w(3,2)
read(*,*) ( (w(i,j),j=1,2),i=1,3 )
内循环外循环
read(*,*)w(1,1),w(1,2),w(2,1),w(2,2),w(3,1),w(3,2)
write(*,100) ( (w(i,j),j=1,2),i=1,3 )
100 format(1x,2f6.2)
输入时,输入的数据按行赋给数组中的各元素。
§ 3 数组的输入和输出
write(*,100)w(1,1),w(1,2),w(2,1),w(2,2),w(3,1),w(3,2)
100 format(1x,2f6.2 / 1x,2f6.2 / 1x,2f6.2)
输出结果:
w(1,1) w(1,2)
w(2,1) w(2,2)
w(3,1) w(3,2)
28
2009-7-29
real w(3,2)
write(*,100) (w(2,i),i=1,2)
100 format(1x,2f6.2)
输出结果,w(2,1) w(2,2)
§ 3 数组的输入和输出
real w(3,3)
write(*,100) (w(i,i),i=1,3)
100 format(1x,f6.2)
输出结果,w(1,1)
w(2,2)
w(3,3)
29
2009-7-29
注,隐 do循环不仅可以用于数组的输入输出,也可用于一般变量的输入输出 。
如:
如:
如:
§ 3 数组的输入和输出
write(*,*) (a,b,i=1,3)
write(*,*) a,b,a,b,a,b
write(*,*) (i,i=1,10)
write(*,*) 1,2,3,4,5,6,7,8,9,10
integer a(10)
write(*,*) (i,a(i),i=1,10,2)
write(*,*) 1,a(1),3,a(3),5,a(5),7,a(7),9,a(9)
30
2009-7-29
§ 4 给数组赋初值 (p204-205)
Fortran语言可以 通过 data语句给变量或数组赋初值 。
注:① 变量表中可以包括变量名、数组名、数组元素名、
数组的隐 do循环,当有多个变量时用逗号隔开;
② 初值表中只允许出现常量 (不能是常量表达式 ),当有多个常量时用逗号隔开。
如:
data 变量表 1/初值表 1/,变量表 2/初值表 2/,…
data a/-1.0/,b/-1.0/,c/-1.0/
data a,b,c/-1.0,-1.0,-1.0/
data a,b,c/ 3*-1.0 / 表示“三个 -1.0”
§ 4 给数组赋初值
31
2009-7-29
如:
③ 当变量表中是数组名时,表示对数组所有的数组元素赋初值,此时初值个数必须与数组的元素个数相同。
如:
如:
integer a(6)
data a(1),a(2),a(3),a(4),a(5),a(6)/1,2,3,4,5,6/
data a(1),a(2),a(3)/1,2,3/
integer a(6)
data a/1,2,3,4,5,6/ data a/1,2,3/
data (a(i),i=1,6)/1,2,3,4,5,6/
data a/3*0,3*1/
data (a(i),i=1,3),(a(i),i=4,6)/3*0,3*1/
§ 4 给数组赋初值
×
32
2009-7-29
§ 4 给数组赋初值
④ 当变量表中使用数组的隐 do循环时,即可以对数组的全部元素赋初值,也可以对数组的部分元素赋初值。
如:
⑤ 当有多个 data语句给同一个变量赋初值时,以最后一个 data语句所赋初值为准。
如:
integer a(6)
data (a(i),i=1,3)/1,2,3/
data i/0/
write(*,*)'i=',i
i=i+1
data i/10/
write(*,*)'i=',i
end
data语句是非执行语句,故是在编译时进行赋初值,不是在执行时赋初值。
i= 10
i= 11
输出结果:
33
2009-7-29
【 9.1】 设矩阵试求两个矩阵的和 c=a+b。 (以矩阵原型输入输出 )
计算方法,cij= aij+ bij
232221
131211
232221
131211
bbb
bbb
b
aaa
aaa
a,
§ 5 程序举例
§ 5 程序举例
34
2009-7-29
real a(2,3),b(2,3),c(2,3)
write(*,*)'请输入 2× 3矩阵 a:'
read(*,*)( (a(i,j),j=1,3),i=1,2)
write(*,*)'请输入 2× 3矩阵 b:'
read(*,*)( (b(i,j),j=1,3),i=1,2)
do 10,i=1,2
do 10,j=1,3
c(i,j)=a(i,j)+b(i,j)
10 continue
write(*,*)'a+b='
write(*,100)( (c(i,j),j=1,3),i=1,2)
100 format(1x,3f7.2)
end § 5 程序举例两个矩阵原型输入结果矩阵原型输出
35
2009-7-29
【 9.2】 计算 c= a·b。
则 c为 l× n的矩阵。
对于矩阵 c中的任一个元素 cij,有:
mllmll
m
m
aaa
aaa
aaa
a
21
22221
11211
nmmnmm
n
n
abb
bbb
bbb
b
21
22221
11211
m
k
kjikij bac
1
§ 5 程序举例
36
2009-7-29
§ 5 程序举例
parameter (l=3,m=2,n=3)
real a(l,m),b(m,n),c(l,n)
write(*,*)'请输入 3× 2矩阵 a:'
read(*,*)( (a(i,j),j=1,m),i=1,l)
write(*,*)'请输入 2× 3矩阵 b:'
read(*,*)( (b(i,j),j=1,n),i=1,m)
do 10,i=1,l
do 10,j=1,n
c(i,j)=0.0
do 10,k=1,m
c(i,j)=c(i,j)+a(i,k)*b(k,j)
10 continue
write(*,*)'a·b='
write(*,100)( (c(i,j),j=1,n),i=1,l)
100 format(1x,3f7.2)
end
m
k
kjikij bac
1
37
2009-7-29
【 9.3】 输入一组学生的学号和一门课的成绩,输出高于平均分的学生学号和成绩。
一个学生的数据包括两项:学号和一门课的成绩。学号用字符型变量 no表示,成绩用实型变量 s表示。
一组学生的学号用一个字符型数组表示,一组学生的成绩用一个实型数组表示。
对于第 i个学生,no(i)是其学号,s (i)是其成绩。
§ 5 程序举例
character*7 no(10)
real s(10)
38
2009-7-29
parameter (n=10)
character*7 no(n)
real s(n),sum,ave
write(*,*)'请输入 ',n,'个学生的学号及成绩,'
read(*,*)(no(i),s(i),i=1,n)
sum=0.0
do 10 i=1,n
sum=sum+s(i)
10 continue
ave=sum/n
§ 5 程序举例
39
2009-7-29
write(*,*)'平均分 =',ave
write(*,*)'学号 成绩 '
write(*,*)'_______________'
do 20 i=1,n
if(s(i).gt.ave) write(*,100)no(i),s(i)
20 continue
100 format(1x,a,f8.2)
write(*,*)'_______________'
end
§ 5 程序举例
40
2009-7-29
【 9.4】 输入一个数,查找其在一个一维数组中是否存在。
若存在,输出它在数组中的下标;若不存在,输出“不存在”。
思路,把该数 x与一维数组 a中的元素从头到尾一一进行比较,这种方法称为顺序查找。
parameter (n=20)
integer a(n),x
data a/55,62,93,87,10,23,38,71,35,91,
$ 99,86,15,9,54,28,64,48,22,67/
write(*,*)'请输入一个数,'
read(*,*)x
§ 5 程序举例
41
2009-7-29
write(*,100) (a(i),i=1,n)
100 format(1x,'一维数组为,'/10(1x,i6))
do 10 i=1,n
if(x.eq.a(i)) goto 20
10 continue
20
write(*,200)x,i
200 format(1x,'数 ',i3,'在数组中的下标为 ',i3)
else
write(*,*)'数 ',x,'在数组中不存在 '
end if
end
§ 5 程序举例
if(i.le.n) then
42
2009-7-29
【 9.5】 把数组中所有的数都向后移动一个位置,最后一个数移到最前面。
a(1) a(2) a(3) a(4) a(5) a(6) a(7) a(8) a(9) a(10)
§ 5 程序举例
① 先把 a(10)放在一个临时变量中保存。
② 从 a(9)开始,a(9) →a(10),a(8) →a(9),a(7)
→a(8),…,最后 a(1) →a(2) 。
③ x→a(1) 。
②
x
①③
43
2009-7-29
parameter (n=10)
integer a(n),x
data a/55,62,93,87,10,23,38,71,35,91/
write(*,100) (a(i),i=1,n)
100 format(1x,'原始的数组为,'/10(1x,i6))
x=a(n)
do 10 i=9,1,-1
a(i+1)=a(i)
10 continue
a(1)=x
write(*,200) (a(i),i=1,n)
200 format(1x,'移动后的数组为,'/10(1x,i6))
end
§ 5 程序举例
44
2009-7-29
【 9.6】 把一个整插到一个有序数组中,插入后新数组仍然保持有序。
14 25 28
a(1) a(2) a(3) a(4) a(5) a(6) a(7) a(8) a(9) a(10) a(11)
33 45 56 68 72 81 95 … …
设有 n=10个整数按由小到大的顺序放在数组 a中,待插入的数为 x,则定义数组时,数组 a长度 ≥n+1。
若 x≥a(10),则不需要移动数组元素位置,x→a(11) ;
否则,则需要移动数组元素位置,(例如 x=30)
① 设 x应插入的位置 (下标 )为 p,则 p=第一个大于 x的数组元素的下标 。
② 将 a(p)~ a(10)的元素后移一个位置。
③ x→a(p) 。
p
33 45 56 68 72 81 95 …30
§ 5 程序举例
45
2009-7-29
integer a(15),x,p
data (a(i),i=1,10)/14,25,28,33,45,56,68,72,81,95/
n=10
write(*,*)?请输入要插入的数,'
read(*,*)x
write(*,100) (a(i),i=1,n)
100 format(1x,?插入前的数组为,'/1x,10i4)
if( x.ge.a(n) )then
a(n+1)=x
else
§ 5 程序举例
46
2009-7-29
p=1
do 10 while(a(p).le.x)
p=p+1
10 continue
do 20 i=n,p,-1
a(i+1)=a(i)
20 continue
a(p)=x
end if
write(*,200) (a(i),i=1,n+1)
200 format(1x,'插入一个数后的数组为,'/1x,11i4)
end
§ 5 程序举例
47
2009-7-29
【 9.7】 将 n个数从小到大重新排列。
采用选择法( P217-P219)
设 n个数存放在一维数组 x(1),x(2),…,x(n) 中。先假设 x(1)中存放的是这 n个数中的最小值。最小值序号 k=1。
①将 x(1)与 x(2),…,x(n) 逐个比较,确定最小值的序号 k,将 x(1)与 x(k)的值对调。此时 x(1)中是 n个数中的最小值。
②假设 最小值序号 k=2,将 x(2)与 x(3),…,x(n) 逐个比较,确定最小值的序号 k,将 x(2)与 x(k)的值对调。此时 x(2)中是剩余 n-1个数中的最小值。
§ 5 程序举例
48
2009-7-29
③假设 最小值序号 k=3,将 x(3)与 x(4),…,x(n) 逐个比较,确定最小值的序号 k,将 x(3)与 x(k)的值对调。此时 x(3)中是剩余 n-2个数中的最小值。
依此类推
…………
④假设 最小值序号 k=n-1,将 x(n-1)与 x(n)比较,
确定最小值的序号 k,将 x(n-1)与 x(k)的值对调。
此时 x(n-1)中是剩余 2个数中的最小值。
⑤显示重新排列后的数组。
§ 5 程序举例
49
2009-7-29
parameter (n=8)
dimension x(n)
data x/3.2,4.1,3.0,5.0,1.2,7.2,5.6,2.6/
write(*,*) x
do 10 i=1,n-1
k=i
do 20 j=i+1,n
if(x(k).lt.x(j)) k=j
20 continue
t=x(i)
x(i)=x(k)
x(k)=t
10 continue
write(*,*) x
end § 5 程序举例选最小值所在序号 n-1次对调
50
2009-7-29
2009-7-29
第 9章 数 组
§ 1 数组的说明和数组元素的引用
§ 2 数组的逻辑结构和存储结构
§ 3 数组的输入和输出
§ 4 给数组赋初值
§ 5 程序举例
2
在日常计算中,经常会遇到一组类型相同数据的计算问题,如计算某班 35名同学某门课的平均成绩。
按之前所学,只能把程序编写为:
read(*,*) f1,f2,……,f35
f=(f1+f2+…+f35)/35.0
print*,f
end
缺点:代码效率低,不实用。
为了方便这种类型的计算,FORTRAN规定了一种“带下标”的 特殊变量,可以把 35个成绩值存入这种特殊变量中,以方便程序编写。
3
2009-7-29
f1
F(1 )
f2
F(2 )
f35
F(35 )
……
……
其中,F(1),F(2),……F(35) 即“带下标”的特殊变量。
称 F是一个 数组,而 F(1),F(2),……F(35) 为数组 F的 35个 数组元素 。
数组属于一种构造数据类型 (基本数据类型组合而成 )。
每个数组代表一组具有同一类型的变量;数组中所包含的变量称为数组元素;通过下标的变化指定元素。
对如前的计算问题,用数组编写要方便得多。
4
2009-7-29
dimension f(1:35)
read(*,*) f
sf=0.0
do 10 k=1,35
sf=sf+f(k)
10 continue
print*,sf/35.0
end
定义了一个一维数组给数组的 35个元素输入数据。
累加计算显示结果对于大批量的数据,可使用事先整理好的数据文件。
k 是变化的下标
5
2009-7-29
一、数组的说明 (定义 )
用 类型说明语句 或 dimension语句定义数组。
其一般形式为:
§ 1 数组的说明和数组元素的引用 (p195-197)
类型说明 (或 dimension) 数组名 (下标下界,下标上界,下标下界,下标上界,… )
第 1维的维说明符第 2维的维说明符
§ 1 数组的说明和数组元素的引用
6
2009-7-29
1,用类型语句定义数组如:
⑴ 数组名后 一对小括号 中包含的是维说明符,多个维说明符时用逗号隔开。
具有一个维说明符的数组为一维数组,具有两个维说明符的数组为二维数组,… 。通常我们 将二维及二维以上的数组称为多维数组 。
⑵ 每个维说明符规定了本维中下标的下界和上界,下界和上界之间用冒号隔开 。
⑶ 下标下界和上界必须是整型常量或整型常量表达式,
且 上界 ≥下界 。
real ia(1:10),w(1:3,1:2)
integer a(0:2,0:1,0:3)
§ 1 数组的说明和数组元素的引用
7
2009-7-29
如:
⑷ 当下标下界为 1时可以省略不写。
⑸ 数组定义 (包括变量定义 )必须放在可执行语句之前。
如:
parameter (low=1,ihig=9)
real ia(low,ihig+1)
integer n
read(*,*) n
real ia(1,n)
real ia(1:10),w(1:3,1:2)
§ 1 数组的说明和数组元素的引用
real ia(10),w(3,2)
不允许定义可变长度的数组。
x=1.0
real ia(1,10)
×
×
8
2009-7-29
2,用 dimension语句定义数组如:
⑴ 若仅有 dimension语句,数组的类型根据数组名首字母的隐式 I-N规则确定。
⑵ 显式类型说明,由 dimension语句与类型说明语句配合进行(由 dimension语句定义数组,由类型说明语句对数组名的类型进行显式说明)。
如:
dimension ia(1:10),w(1:3,1:2),a(0:2,0:1,0:3)
dimension ia(1:10),w(1:3,1:2),a(0:2,0:1,0:3)
integer a
real ia,w
§ 1 数组的说明和数组元素的引用
9
2009-7-29
二、数组元素的引用数组元素使用的一般形式:
数组名 (下标 1,下标 2…)
如:
⑴ 标准 Fortran77中,除了在输入和输出语句中外,其它场合不允许对数组进行整体操作,只能对数组元素逐个进行操作 。
integer a(10)
do 10,i=1,10
a(i)=0.0
10 continue
§ 1 数组的说明和数组元素的引用
10
2009-7-29
⑵ 数组元素的下标允许是任意算术表达式,如果表达式的类型为非整型时则自动取整。
⑶ 数组元素的下标值必须落在该维的上界和下界之内,即满足,下界 ≤下标 ≤上界 。
对于下标越界,大部分 Fortran系统在编译和连接时都不会报错,程序都会执行,但其结果会有问题。因此,对于数组运算,尤其是采用循环时,
对于下标的范围要注意控制。
§ 1 数组的说明和数组元素的引用
11
2009-7-29
一、一维数组的逻辑结构和存储结构
1,逻辑结构一维数组是线性表的一种表现形式 。
线性表的特点,⑴ 存在唯一的一个被称做“第一个”
的数据元素; ⑵ 存在唯一的一个被称做“最后一个”的数据元素; ⑶ 除第一个之外,表中的每个数据元素均只有一个前驱; ⑷ 除最后一个之外,表中的每个数据元素均只有一个后继。
一维数组的逻辑结构是 按数组元素下标值由小到大排列的一个线性表,每个元素的下标值确定了该元素在表中的位置。
§ 2 数组的逻辑结构和存储结构 (p198-200)
§ 2 数组的逻辑结构和存储结构
12
2009-7-29
2,存储结构一维数组在计算机内存中 占用一串连续的存储单元,
每个元素在内存中的存放顺序与逻辑结构是一致的。
如:
§ 2 数组的逻辑结构和存储结构
real ia(10)
ia(1)
ia(2)
ia(3)
ia(4)
ia(5)
ia(6)
ia(7)
ia(8)
ia(9)
ia(10)
13
2009-7-29
二、二维数组的逻辑结构和存储结构
1,逻辑结构可以看成是一个矩阵,每个元素的第 1个下标表示元素在矩阵中的行号,第 2个下标表示元素在矩阵中的列号。
如:
2,存储结构在内存中占有连续的存储单元 (存储单元是一维的 )。
二维数组在内存中 按列存放,先存放第 1列的元素,再存放第 2列的元素,依此类推,…… 。
real w(3,2) w(1,1) w(1,2) w(2,1) w(2,2)
w(3,1) w(3,2)
§ 2 数组的逻辑结构和存储结构
14
2009-7-29
如:
逻辑结构:
三、三维数组的逻辑结构和存储结构逻辑结构,可以看成是由多个二维矩阵 (或若干页表格 )
组成的。每个元素的第 3个下标表示元素所在的 页号,第
1个下标表示元素在该页表格的 行号,第 2个下标表示元素在该页表格的 列号 。(教材 p200例子)
存储结构,也占有一串连续的存储单元,依次存放各二维矩阵 (或各表格 )的所有元素 (按列存放 ) 。可以认为
“第1下标变化最快,中间次之,最后的下标变化最慢”
real w(3,2)
w(1,1) w(1,2)
w(2,1) w(2,2)
w(3,1) w(3,2)
存储结构,w(1,1)
w(2,1)
w(3,1)
w(1,2)
w(2,2)
w(3,2)
§ 2 数组的逻辑结构和存储结构
15
2009-7-29
注意:
存储结构,一个数组在计算机内存中实际存放的形式。
Fortran程序可以在一个输入 / 输出语句中通过数组名对所有数组元素进行一次性的输入 / 输出;
采用这种形式时,输入 / 输出的顺序是和存储结构的顺序一致的。
§ 2 数组的逻辑结构和存储结构
dimension c(2,2,2),问 c的元素存储顺序如何?
c(1,1,1) c(2,1,1) c(1,2,1) c(2,2,1) c(1,1,2) c(2,1,2)
c(1,2,2) c(2,2,2)
16
2009-7-29
Fortran中数组的输入输出有三种形式:
利用 do循环对数组进行输入输出
在输入输出语句中用数组名输入输出整个数组
在输入输出语句中使用 隐 do循环一、利用 do循环对数组进行输入输出如:
§ 3 数组的输入和输出 (p200-204)
integer a(10)
do 10 i=1,10
read(*,*)a(i)
10 continue
do 10 i=1,10
write(*,*)a(i)
10 continue
§ 3 数组的输入和输出
17
2009-7-29
如:
注,⑴ 在一个输入语句输入数据时,只有在回车后,输入的数据才会被该 read语句中的变量接收。
在通过键盘输入数据时,数据输入的形式是( ):
A,一次输入 10个数,然后回车。
B,每次输入 1个数,然后回车;共输入十次。
C,无所谓,每次输入几个数都行,都可以回车;如果不够 10个,后面接着输入。
integer a(10)
do 10 i=1,10
read(*,*)a(i)
10 continue
§ 3 数组的输入和输出
B
18
2009-7-29
注,⑴ 在一个输入语句输入数据时,只有在回车后,输入的数据才会被该 read语句中的变量接收。
⑵ 在一个输入语句输入数据时,若回车时输入的数据个数 > 该输入语句中的变量个数,则多余的数据作废。
⑶ 在一个输入语句输入数据时,若回车时输入的数据个数 < 该输入语句中的变量个数,则 read语句会继续等待输入数据,直到输入数据的个数足够为止。
如:
§ 3 数组的输入和输出
integer a(10)
read(*,*)a(1),a(2),a(3),…,a(10)
A,一次输入 10个数,然后回车。
C,无所谓,每次输入几个数都行,都可以回车;如果不够 10个,后面接着输入。
19
2009-7-29
integer a(10)
do 10 i=1,10
write(*,*)a(i)
10 continue
相当于有 10个 write(*,*)语句。
输出结果,每行输出 1个数组元素的值,共输出 10行。
integer a(10)
do 10 i=1,10,2
write(*,100)a(i)
10 continue
100 format(1x,2I4)
相当于有 5个格式输出语句,
每个格式输出语句对应一个输出记录。
输出结果,输出数组 a中下标为奇数的 5个数组元素,每行输出 1个元素,共输出 5行。
§ 3 数组的输入和输出
20
2009-7-29
如:
real w(3,2)
do 10 i=1,3
do 20 j=1,2
read(*,*) w(i,j)
20 continue
10 continue
§ 3 数组的输入和输出
read(*,*) w(1,1)
read(*,*) w(1,2)
read(*,*) w(2,1)
read(*,*) w(2,2)
read(*,*) w(3,1)
read(*,*) w(3,2)
输入形式:
每次输入 1个数,然后回车;共输入 6次。
21
2009-7-29
※,使用 do循环对数组进行输入输出,方法的 缺点:
效率低,一个输入 /输出语句只能输入 /输出一个数据。
real w(3,2)
do 10 i=1,2
do 20 j=1,3
write(*,100)w( j,i)
100 format(1x,2f6.2)
20 continue
10 continue
§ 3 数组的输入和输出
write(*,100) w(1,1)
write(*,100) w(2,1)
write(*,100) w(3,1)
write(*,100) w(1,2)
write(*,100) w(2,2)
write(*,100) w(3,2)
100 format(1x,2f6.2)
输出结果:
按列输出,每行输出 1个数组元素的值,共输出 6行。
22
2009-7-29
二、在输入输出语句中用数组名输入输出整个数组当在输入 /输出语句中仅使用数组名时,相当于 对数组的全部元素按在内存中的排列顺序进行输入 /输出 。
如,integer a(10)
read(*,*) a
write(*,100) a
100 format(1x,2I4)
read(*,*)a(1),a(2),a(3),a(4),a(5),a(6),a(7),a(8),a(9),a(10)
write(*,100)a(1),a(2),a(3),a(4),a(5),a(6),a(7),a(8),a(9),a(10)
100 format(1x,2I4 / 1x,2I4 / 1x,2I4 / 1x,2I4 / 1x,2I4)
§ 3 数组的输入和输出输出结果:
每行输出两个数组元素,共输出
5行。
23
2009-7-29
real w(3,2)
read(*,*) w
如:
read(*,*)w(1,1),w(2,1),w(3,1),w(1,2),w(2,2),w(3,2)
write(*,100) w
100 format(1x,2f6.2)
write(*,100)w(1,1),w(2,1),w(3,1),w(1,2),w(2,2),w(3,2)
100 format(1x,2f6.2 / 1x,2f6.2 / 1x,2f6.2)
输入时,输入的数据按列赋给数组中的各元素。
输出结果,w(1,1) w(2,1)
w(3,1) w(1,2)
w(2,2) w(3,2)
§ 3 数组的输入和输出
3
3 3 )
w(1,1) w(2,1) w(3,1)
w(1,2) w(2,2) w(3,2)
24
2009-7-29
※,使用数组名输入输出整个数组”方法的 缺点:
一个输入 /输出语句可以输入 /输出数组的全部数组元素;
但 无法控制输入 /输出元素的顺序,也无法控制输入 /输出元素的个数 。
三、在输入输出语句中使用隐含 do循环指把 do循环放在输入输出语句中,这种 do循环也称为隐 do循环 或 隐含 do循环 。
优点:
能控制在一个输入 /输出语句中输入 /输出多个数组元素 (全部或部分数组元素 )。
也能控制输入 /输出数组元素的顺序。
数组的输入 /输出推荐使用该方法。
§ 3 数组的输入和输出
25
书写方式,
2重隐循环,((输入输出元素,v=e1,e2,e3),u=f1,f2,f3)
3重隐循环,
(((输入输出元素,v=e1,e2,e3),u=f1,f2,f3),w=g1,g2,g3)))
1重隐循环,(输入输出元素,v=e1,e2,e3)
隐循环体 循环控制隐循环体 内循环控制 外循环控制
隐循环 作用,由循环控制列出隐循环体中的元素 。一般置于输入输出语句和 DATA语句中。
§ 3 数组的输入和输出
26
2009-7-29
integer a(10)
read(*,*) (a(i),i=1,10)
如,i是隐循环变量,初值为 1,
终值为 10,步长为 1。
隐 do循环外面必须加一对小括号。
read(*,*)a(1),a(2),a(3),…,a(9),a(10)
write(*,100) (a(i),i=1,10)
100 format(1x,5f6.2)
a(1) a(2) a(3) a(4) a(5)
a(6) a(7) a(8) a(9) a(10)
write(*,100) (a(i),i=1,10,2)
100 format(1x,5f6.2) a(1) a(3) a(5) a(7) a(9)
write(*,100) (a(i),i=10,1,-2)
100 format(1x,5f6.2) a(10) a(8) a(6) a(4) a(2)
§ 3 数组的输入和输出
27
2009-7-29
real w(3,2)
read(*,*) ( (w(i,j),j=1,2),i=1,3 )
内循环外循环
read(*,*)w(1,1),w(1,2),w(2,1),w(2,2),w(3,1),w(3,2)
write(*,100) ( (w(i,j),j=1,2),i=1,3 )
100 format(1x,2f6.2)
输入时,输入的数据按行赋给数组中的各元素。
§ 3 数组的输入和输出
write(*,100)w(1,1),w(1,2),w(2,1),w(2,2),w(3,1),w(3,2)
100 format(1x,2f6.2 / 1x,2f6.2 / 1x,2f6.2)
输出结果:
w(1,1) w(1,2)
w(2,1) w(2,2)
w(3,1) w(3,2)
28
2009-7-29
real w(3,2)
write(*,100) (w(2,i),i=1,2)
100 format(1x,2f6.2)
输出结果,w(2,1) w(2,2)
§ 3 数组的输入和输出
real w(3,3)
write(*,100) (w(i,i),i=1,3)
100 format(1x,f6.2)
输出结果,w(1,1)
w(2,2)
w(3,3)
29
2009-7-29
注,隐 do循环不仅可以用于数组的输入输出,也可用于一般变量的输入输出 。
如:
如:
如:
§ 3 数组的输入和输出
write(*,*) (a,b,i=1,3)
write(*,*) a,b,a,b,a,b
write(*,*) (i,i=1,10)
write(*,*) 1,2,3,4,5,6,7,8,9,10
integer a(10)
write(*,*) (i,a(i),i=1,10,2)
write(*,*) 1,a(1),3,a(3),5,a(5),7,a(7),9,a(9)
30
2009-7-29
§ 4 给数组赋初值 (p204-205)
Fortran语言可以 通过 data语句给变量或数组赋初值 。
注:① 变量表中可以包括变量名、数组名、数组元素名、
数组的隐 do循环,当有多个变量时用逗号隔开;
② 初值表中只允许出现常量 (不能是常量表达式 ),当有多个常量时用逗号隔开。
如:
data 变量表 1/初值表 1/,变量表 2/初值表 2/,…
data a/-1.0/,b/-1.0/,c/-1.0/
data a,b,c/-1.0,-1.0,-1.0/
data a,b,c/ 3*-1.0 / 表示“三个 -1.0”
§ 4 给数组赋初值
31
2009-7-29
如:
③ 当变量表中是数组名时,表示对数组所有的数组元素赋初值,此时初值个数必须与数组的元素个数相同。
如:
如:
integer a(6)
data a(1),a(2),a(3),a(4),a(5),a(6)/1,2,3,4,5,6/
data a(1),a(2),a(3)/1,2,3/
integer a(6)
data a/1,2,3,4,5,6/ data a/1,2,3/
data (a(i),i=1,6)/1,2,3,4,5,6/
data a/3*0,3*1/
data (a(i),i=1,3),(a(i),i=4,6)/3*0,3*1/
§ 4 给数组赋初值
×
32
2009-7-29
§ 4 给数组赋初值
④ 当变量表中使用数组的隐 do循环时,即可以对数组的全部元素赋初值,也可以对数组的部分元素赋初值。
如:
⑤ 当有多个 data语句给同一个变量赋初值时,以最后一个 data语句所赋初值为准。
如:
integer a(6)
data (a(i),i=1,3)/1,2,3/
data i/0/
write(*,*)'i=',i
i=i+1
data i/10/
write(*,*)'i=',i
end
data语句是非执行语句,故是在编译时进行赋初值,不是在执行时赋初值。
i= 10
i= 11
输出结果:
33
2009-7-29
【 9.1】 设矩阵试求两个矩阵的和 c=a+b。 (以矩阵原型输入输出 )
计算方法,cij= aij+ bij
232221
131211
232221
131211
bbb
bbb
b
aaa
aaa
a,
§ 5 程序举例
§ 5 程序举例
34
2009-7-29
real a(2,3),b(2,3),c(2,3)
write(*,*)'请输入 2× 3矩阵 a:'
read(*,*)( (a(i,j),j=1,3),i=1,2)
write(*,*)'请输入 2× 3矩阵 b:'
read(*,*)( (b(i,j),j=1,3),i=1,2)
do 10,i=1,2
do 10,j=1,3
c(i,j)=a(i,j)+b(i,j)
10 continue
write(*,*)'a+b='
write(*,100)( (c(i,j),j=1,3),i=1,2)
100 format(1x,3f7.2)
end § 5 程序举例两个矩阵原型输入结果矩阵原型输出
35
2009-7-29
【 9.2】 计算 c= a·b。
则 c为 l× n的矩阵。
对于矩阵 c中的任一个元素 cij,有:
mllmll
m
m
aaa
aaa
aaa
a
21
22221
11211
nmmnmm
n
n
abb
bbb
bbb
b
21
22221
11211
m
k
kjikij bac
1
§ 5 程序举例
36
2009-7-29
§ 5 程序举例
parameter (l=3,m=2,n=3)
real a(l,m),b(m,n),c(l,n)
write(*,*)'请输入 3× 2矩阵 a:'
read(*,*)( (a(i,j),j=1,m),i=1,l)
write(*,*)'请输入 2× 3矩阵 b:'
read(*,*)( (b(i,j),j=1,n),i=1,m)
do 10,i=1,l
do 10,j=1,n
c(i,j)=0.0
do 10,k=1,m
c(i,j)=c(i,j)+a(i,k)*b(k,j)
10 continue
write(*,*)'a·b='
write(*,100)( (c(i,j),j=1,n),i=1,l)
100 format(1x,3f7.2)
end
m
k
kjikij bac
1
37
2009-7-29
【 9.3】 输入一组学生的学号和一门课的成绩,输出高于平均分的学生学号和成绩。
一个学生的数据包括两项:学号和一门课的成绩。学号用字符型变量 no表示,成绩用实型变量 s表示。
一组学生的学号用一个字符型数组表示,一组学生的成绩用一个实型数组表示。
对于第 i个学生,no(i)是其学号,s (i)是其成绩。
§ 5 程序举例
character*7 no(10)
real s(10)
38
2009-7-29
parameter (n=10)
character*7 no(n)
real s(n),sum,ave
write(*,*)'请输入 ',n,'个学生的学号及成绩,'
read(*,*)(no(i),s(i),i=1,n)
sum=0.0
do 10 i=1,n
sum=sum+s(i)
10 continue
ave=sum/n
§ 5 程序举例
39
2009-7-29
write(*,*)'平均分 =',ave
write(*,*)'学号 成绩 '
write(*,*)'_______________'
do 20 i=1,n
if(s(i).gt.ave) write(*,100)no(i),s(i)
20 continue
100 format(1x,a,f8.2)
write(*,*)'_______________'
end
§ 5 程序举例
40
2009-7-29
【 9.4】 输入一个数,查找其在一个一维数组中是否存在。
若存在,输出它在数组中的下标;若不存在,输出“不存在”。
思路,把该数 x与一维数组 a中的元素从头到尾一一进行比较,这种方法称为顺序查找。
parameter (n=20)
integer a(n),x
data a/55,62,93,87,10,23,38,71,35,91,
$ 99,86,15,9,54,28,64,48,22,67/
write(*,*)'请输入一个数,'
read(*,*)x
§ 5 程序举例
41
2009-7-29
write(*,100) (a(i),i=1,n)
100 format(1x,'一维数组为,'/10(1x,i6))
do 10 i=1,n
if(x.eq.a(i)) goto 20
10 continue
20
write(*,200)x,i
200 format(1x,'数 ',i3,'在数组中的下标为 ',i3)
else
write(*,*)'数 ',x,'在数组中不存在 '
end if
end
§ 5 程序举例
if(i.le.n) then
42
2009-7-29
【 9.5】 把数组中所有的数都向后移动一个位置,最后一个数移到最前面。
a(1) a(2) a(3) a(4) a(5) a(6) a(7) a(8) a(9) a(10)
§ 5 程序举例
① 先把 a(10)放在一个临时变量中保存。
② 从 a(9)开始,a(9) →a(10),a(8) →a(9),a(7)
→a(8),…,最后 a(1) →a(2) 。
③ x→a(1) 。
②
x
①③
43
2009-7-29
parameter (n=10)
integer a(n),x
data a/55,62,93,87,10,23,38,71,35,91/
write(*,100) (a(i),i=1,n)
100 format(1x,'原始的数组为,'/10(1x,i6))
x=a(n)
do 10 i=9,1,-1
a(i+1)=a(i)
10 continue
a(1)=x
write(*,200) (a(i),i=1,n)
200 format(1x,'移动后的数组为,'/10(1x,i6))
end
§ 5 程序举例
44
2009-7-29
【 9.6】 把一个整插到一个有序数组中,插入后新数组仍然保持有序。
14 25 28
a(1) a(2) a(3) a(4) a(5) a(6) a(7) a(8) a(9) a(10) a(11)
33 45 56 68 72 81 95 … …
设有 n=10个整数按由小到大的顺序放在数组 a中,待插入的数为 x,则定义数组时,数组 a长度 ≥n+1。
若 x≥a(10),则不需要移动数组元素位置,x→a(11) ;
否则,则需要移动数组元素位置,(例如 x=30)
① 设 x应插入的位置 (下标 )为 p,则 p=第一个大于 x的数组元素的下标 。
② 将 a(p)~ a(10)的元素后移一个位置。
③ x→a(p) 。
p
33 45 56 68 72 81 95 …30
§ 5 程序举例
45
2009-7-29
integer a(15),x,p
data (a(i),i=1,10)/14,25,28,33,45,56,68,72,81,95/
n=10
write(*,*)?请输入要插入的数,'
read(*,*)x
write(*,100) (a(i),i=1,n)
100 format(1x,?插入前的数组为,'/1x,10i4)
if( x.ge.a(n) )then
a(n+1)=x
else
§ 5 程序举例
46
2009-7-29
p=1
do 10 while(a(p).le.x)
p=p+1
10 continue
do 20 i=n,p,-1
a(i+1)=a(i)
20 continue
a(p)=x
end if
write(*,200) (a(i),i=1,n+1)
200 format(1x,'插入一个数后的数组为,'/1x,11i4)
end
§ 5 程序举例
47
2009-7-29
【 9.7】 将 n个数从小到大重新排列。
采用选择法( P217-P219)
设 n个数存放在一维数组 x(1),x(2),…,x(n) 中。先假设 x(1)中存放的是这 n个数中的最小值。最小值序号 k=1。
①将 x(1)与 x(2),…,x(n) 逐个比较,确定最小值的序号 k,将 x(1)与 x(k)的值对调。此时 x(1)中是 n个数中的最小值。
②假设 最小值序号 k=2,将 x(2)与 x(3),…,x(n) 逐个比较,确定最小值的序号 k,将 x(2)与 x(k)的值对调。此时 x(2)中是剩余 n-1个数中的最小值。
§ 5 程序举例
48
2009-7-29
③假设 最小值序号 k=3,将 x(3)与 x(4),…,x(n) 逐个比较,确定最小值的序号 k,将 x(3)与 x(k)的值对调。此时 x(3)中是剩余 n-2个数中的最小值。
依此类推
…………
④假设 最小值序号 k=n-1,将 x(n-1)与 x(n)比较,
确定最小值的序号 k,将 x(n-1)与 x(k)的值对调。
此时 x(n-1)中是剩余 2个数中的最小值。
⑤显示重新排列后的数组。
§ 5 程序举例
49
2009-7-29
parameter (n=8)
dimension x(n)
data x/3.2,4.1,3.0,5.0,1.2,7.2,5.6,2.6/
write(*,*) x
do 10 i=1,n-1
k=i
do 20 j=i+1,n
if(x(k).lt.x(j)) k=j
20 continue
t=x(i)
x(i)=x(k)
x(k)=t
10 continue
write(*,*) x
end § 5 程序举例选最小值所在序号 n-1次对调
50
2009-7-29