二维数组

〖语法分析〗

  一维数组在编程中多用于描述线性的关系:如一组数;一组成绩;一组解答等。数组元素只有一个下标,表明该元素在数组中的位置。二维数组在编程中多数用于描述二维的关系:如地图、棋盘、城市街道、迷宫等等。而二维数组元素有两个下标:第一个下标表示该元素在第几行,第二个下标表示在第几列。二维数组的定义格式如下:
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.

 

posted on 2008-11-17 13:45  sandboy  阅读(830)  评论(0)    收藏  举报