您现在的位置:小学生自学网>> 信息>> pascal语言>> 基础教程

pascal第十四讲:二维数组

作者: 来源: 发布时间:2009年05月12日 点击数:
 

二维数组
〖语法分析〗

  一维数组在编程中多用于描述线性的关系:如一组数;一组成绩;一组解答等。数组元素只有一个下标,表明该元素在数组中的位置。二维数组在编程中多数用于描述二维的关系:如地图、棋盘、城市街道、迷宫等等。而二维数组元素有两个下标:第一个下标表示该元素在第几行,第二个下标表示在第几列。二维数组的定义格式如下:
var
   a:array[1..10,1..5] of integer;
   其中:a是数组名,由程序员自定;array和of是定义数组的保留字;(这两点和一维数组定义的格式一样)中括号中的两个范围表示二维数组共有多少行、多少列(第一个范围表示行数,第二个范围表示列数);最后一个表示数组元素的类型,规定和一维数组一样。如上例,定义了一个二维数组a,共有10行5列。

   使用二维数组要注意:
   1、数组元素的指称:数组名[行号,列号]。如第三行第四个元素:a[3,4]。
   对某一行进行处理。如累加第4行的数据。则固定行号为4。如:for i:=1 to 5 do s:=s+a[4,i];
   对某一列进行处理。如累加第4列的数据。则固定列号为4。如:for i:=1 to 10 do s:=s+a[i,4];

   2、二维数组的输入输出要用双重循环来控制:
for i:=1 to 10 do{————控制行数}
begin
   for j:=1 to 5 do read(a[i,j]){————第一行读入5个元素}
   readln;{————读入一个换行符}
end;
{————最常用的方法:从键盘读入数据初始化二维数组}
for i:=1 to 10 do
   for j:=1 to 5 do a[i,j]:=0;
{————最常用的方法:将二维数组清0}
for i:=1 to 10 do
begin
   for j:=1 to 5 do write(a[i,j]:4);
   writeln;
end;
{————最常用的输出方法:按矩阵形式输出二维数组的值}

   3、二维数组的应用:
例1:竞赛小组共有20位同学,这学期每位同学共参与了三项比赛,请统计每位同学的平均分。
分析:定义一个20行3列的二维数组来存放这些成绩。定义一个20个元素的一维数组来存放平均分。
program p1;
var
   a:array [1..20,1..3] of integer;
   b:array [1..20] of real;
   i,j:integer;
begin
   for i:=1 to 20 do
   begin
      for j:=1 to 3 do read(a[i,j]);
     readln;
   end;
{————从键盘上读入20个同学的三次竞赛成绩}
   for i:=1 to 20 do b[i]:=0;
{————先将平均分数组清0}
   for i:=1 to 20 do
   begin
     for j:=1 to 3 do b[i]:=b[i]+a[i,j];{————计算总分}
     b[i]:=b[i]/3;{————计算平均分}
   end;
   for i:=1 to 20 do write(b[i]:5:1);
{————输出平均分}
writeln;
end.

例2:设有一程序:
   program ex5_3;
   const n=3;
   type matrix=array[1..n,1..n]of integer;
   var a:matrix;
    i,j:1..n;
   begin
    for i:=1 to n do
    begin
     for j:=1 to n do
      read(a[i,j]);
     readln;
    end;
   for i:=1 to n do
   begin
    for j:=1 to n do
     write(a[j,i]:5);
    writeln;
   end;
   end.
   且运行程序时的输入为:
   2□1□3←┘
   3□3□1←┘
   1□2□1←┘
   则程序的输出应是:
   2□3□1
   1□3□2
   3□1□1

例3:输入一串字符,字符个数不超过100,且以"."结束。 判断它们是否构成回文。
   分析:所谓回文指从左到右和从右到左读一串字符的值是一样的,如12321,ABCBA,AA等。先读入要判断的一串字符(放入数组letter中),并记住这串字符的长度,然后首尾字符比较,并不断向中间靠拢,就可以判断出是否为回文。
   源程序如下:
   program ex5_5;
   var  
     letter  : array[1..100]of char;
     i,j   : 0..100;
     ch   : char;
   begin
    {读入一个字符串以'.'号结束}
    write('Input a string:');
    i:=0;read(ch);
    while ch<>'.' do
    begin
     i:=i+1;letter[i]:=ch;
     read(ch)
    end;
    {判断它是否是回文}
    j:=1;
    while (j<i)and(letter[j]=letter[i])do
    begin
     i:=i-1;j:=j+1;
    end;
    if j>=i then writeln('Yes.')
    else writeln('No.');
   end.

例4:奇数阶魔阵
   魔阵是用自然数1,2,3…,n2填n阶方阵的各个元素位置,使方阵的每行的元素之和、每列元素之和及主对角线元素之和均相等。奇数阶魔阵的一个算法是将自然数数列从方阵的中间一行最后一个位置排起,每次总是向右下角排(即Aij的下一个是Ai+1,j+1)。但若遇以下四种情形,则应修正排数法。
   (1) 列排完(即j=n+1时),则转排第一列;
   (2) 行排完(即i=n+1时),则转排第一行;
   (3) 对An,n的下一个总是An,n-1;
   (4) 若Aij已排进一个自然数,则排Ai-1,j-2。

   例如3阶方阵,则按上述算法可排成:
           4 3 8
           9 5 1
           2 7 6

  有了以上的算法,解题主要思路可用伪代码描述如下:
   1 in div 2+1,yn /*排数的初始位置*/
   2 a[i,j]1;
   3 for k:=2 to n*n do
   4 计算下一个排数位置(i,j);
   5 if a[i,j]<>0 then
   6 ii-1;
   7 jj-2;
   8 a[i,j]k;
   9 endfor

   对于计算下一个排数位置,按上述的四种情形进行,但我们应先处理第三处情况。算法描述如下:
   1 if (i=n)and(j=n) then
   2 jj-1; /*下一个位置为(n,n-1)*/;
   3 else
   4 ii mod n +1;
   5 jj mod n +1;
   6 endif;

   源程序如下:
   program ex5_7;
   var
    a : array[1..99,1..99]of integer;
    i,j,k,n : integer;
   begin
    fillchar(a,sizeof(a),0);
    write('n=');readln(n);
    i:=n div 2+1;j:=n;
    a[i,j]:=1;
    for k:=2 to n*n do
     begin
      if (i=n)and(j=n) then
       j:=j-1
      else
       begin
        i:=i mod n +1;
        j:=j mod n +1;
       end;
      if a[i,j]<>0 then
       begin
        i:=i-1;
        j:=j-2;
       end;
      a[i,j]:=k;
     end;
    for i:=1 to n do
     begin
      for j:=1 to n do
       write(a[i,j]:5);
      writeln;
     end;
   end.


练习题:
1、 输入N个同学的语、数、英三科成绩,计算他们的总分与平均分,并统计出每个同学的名次,最后以表格的形式输出。
2、输入10个学生的姓名,编一程序将它们按字母的顺序排列。
3、 输出杨辉三角的前N行(N<10)。
       1
       1 1
       1 2 1
       1 3 3 1
       1 4 6 4 1

4、求一个5 X 5数阵中的马鞍数,输出它的位置。所谓马鞍数,是指在行上最小而在列上最大的数。如下:
5 6 7 8 9
4 5 6 7 8
3 4 5 2 1
2 3 4 9 0
1 2 5 4 8
则1行1列上的数就是马鞍数。

5、验证数学黑洞:所有四位数,除了数字全相同的外,其它的,经过不多于七次的下列操作,一定可以得到6174;并且,一旦得到6174之后,就掉进黑洞,再也得不到其它的数(6174:7641-1467 = 6174):
将这个四位数的数字按从大到小和从小到大重组成两个数,大数减去小数。
例:输入3214
(1)4321 - 1234 = 3087
(2)8730 - 378 = 8352
(3)8532 - 2358 = 6174

6、猴子选大王:有M个猴子围成一圈,每个有一个编号,编号从1到M。打算从中选出一个大王。经过协商,决定选大王的规则如下:从第一个开始,每隔N个,数到的猴子出圈,最后剩下来的就是大王。
要求:从键盘输入M,N,编程计算哪一个编号的猴子成为大王。

7、有M个人围成一圈,每人有一个编号,从编号为1的人开始,每隔N个出圈,按出圈次序排成一列,其编号刚好按顺序从1到M。要求:从键盘输入M,N,编程计算并输出这M个人原来在圈中的位置。

8、前N个自然数排成一串: X1,X2,X3.....Xn,先取出x1,将x2,x3移到数串尾,再取出x4,将x4,x6移到数串尾,....... 类推直至取完.取出的序列恰好是:1,2,3......n,要求输入N,求原来的数串的排列方式.

9、猴子捉兔子:围绕着山顶有10个洞,狐狸要吃兔子,兔子说:“可以,但必须找到我,???? ???我就藏身于这十个洞中,你从10号洞出发,先到1号洞找,第二次隔1个洞找,第三次隔2个洞找,以后如此类推,次数不限。”但狐狸从早到晚进进出出了1000次,仍没有找到兔子。问兔子究竟藏在哪个洞里?