Заполнение двухмерного массива

По правилу

Пример

Составить программу, запрашивающую координаты ферзя на шахматной доске и показывающую поля дос­ки, находящиеся под боем (на доске нет других фигур).

Решение

Заметим, что шахматную доску удобно представить в виде двумерного массива размером 8х8. Координаты ферзя можно задать двумя числами (номером строки и номером столбца), но в шахматах принято указывать букву и число. Буква указывает номер строки, а число − номер столбца. Поэтому не будем отступать от тради­ций и введем координаты именно таким образом. В программе сделаем проверку правильности ввода, и если все правильно, то переведем букву в соответствующее ей число (a-1, b-2, c-3, d-4, е-5, f-6, g-7, h-8), тогда будет удобнее работать.

Для решения задачи полезно знать следующие свойст­ва шахматной доски. Все диагонали делятся на восходя­щие и нисходящие:

Каждая диагональ обладает следующими свойствами:

· для элементов любой восходящей диагонали сум­ма номеров строки и столбца постоянна, причем для разных диагоналей − разная, то есть i+j=const1;

· для элементов нисходящих диагоналей разность номеров строки и столбца тоже постоянна и для разных диагоналей разная, то есть i-j=const2.

Это необходимо знать для того, чтобы определить номера диагоналей, на которых находится ферзь. Вся программа будет такой:

Program Example_120;

Const n=8;

Type dmyarray=Array[1..n,1..n] Of Integer;

Var A: dmyarray;

c: Char;

str, stl: Integer;

{str - номер строки, stl - номер столбца}

Function Place(ch: Char): Integer;

Var k: Integer;

Begin

Case ch Of

'a': k:=1; 'b': k:=2; 'c': k:=3;

'd': k:=4; 'e': k:=5; 'f: k:=6;

'g': k:=7; 'h': k:=8;

Place:=k;

End;

Procedure Init(k, l: Integer;

Var x: dmyarray);

{k - номер строки, l - номер столбца, где стоит ферзь}

Var i, j: Integer;

Begin

For i:=1 To n Do

For j:=1 To n Do {Под боем клетки,

находящиеся с клеткой, на которой стоит

ферзь, на одной вертикали, горизонтали,

восходящей или нисходящей диагонали.

Клетки, находящиеся под боем, мы

помечаем 1, остальные помечаем 0.}

If (i=k) Or (j=1) Or (i+j=k+1)

Or (i-j=k-l)

Then x[i, j]:=1 Else x[i, j]:=0;

x[k, l]:=2;

{На этой клетке стоит ферзь}

End;

Procedure Print(x: dmyarray);

Var i, j: Integer;

Begin

For i:=1 To n Do

Begin

For j:=1 To n Do

Case x[i, j] Of

0: Write (' ':3);

1: Write ('*':3);

2: Write ('F':3);

End;

Writeln;

End;

Begin

Writeln('Введите координаты ферзя');

Readln(с, stl);

If (c<'a') Or (c>'h') Or (stl<1)

Or (stl>n) Then

Writeln('Некорректный ввод')

Else

Begin

str:=Place(с);

Init(str, stl, A);

Print(A);

End;

Readln;

End.

Можно функцию Place составить иначе:

Function Place(ch: Char): Integer;

Var k: Integer;

Begin

Place:=0rd(ch)-Ord('a')+1;

End;

В этом случае она будет более рациональна.

Пример 2

Заполнить массив А размером n×m следующим об­разом (по "змейке");

Например, при n=6 и m=8:

1 2 3 4 5 6 7 8

16 15 14 13 12 11 10 9

17 18 19 20 21 22 23 24

32 31 30 29 28 27 26 25

33 34 35 36 37 38 39 40

48 47 46 45 44 43 42 41

Решение

Для того чтобы заполнить массив указанным об­разом, надо вывести правило заполнения. В данном случае правило будет таким: если ряд нечетный (то есть когда номер строки − нечетное число), то А[i, j]=(i-1)*m+j, иначе (то есть когда строка чет­ная) A[i, j]=i*m-j+1. В соответствии с этим прави­лом составляем процедуру заполнения массива:

Program Example_121;

Procedure Fill (Varx: dmyarray);

Var i, j: Integer;

Begin

For i:=1 To n Do

For j:=1 To m Do

If i Mod 2=1 Then x[i, j]:=(i-1)*m+j

Else x[i, j]:=i*m-j+1;

End;

Вставка и удаление элементов

Вставка строки

Мы уже рассматривали операции вставки для одно­мерных массивов. Обобщим их для двухмерных.

Пример

Вставить строку из нулей после строки с номером k.

Решение

Для решения этой задачи необходимо:

1. Первые k строк оставить без изменения.

2. Все строки после k−й сдвинуть на одну вниз, это лучше начать с последней строки и идти до (k+1)−й.

3. Присвоить значения элементам (k+1) строки.

Кроме того, необходимо обратить внимание на раз­мерность массива. Так как мы вставляем строку, то не­обходимо иметь одну строку "в запасе".

Program Example_122;

Const n=5; m:=7;

Type dmyarray=Array[1..n+1,1..m]

Of Integer;

Var A: dmyarray; k:Integer;

Теперь опишем процедуру вставки:

Procedure Insert(k1: Integer;

Var x: dmyarray);

Var i, j: Integer;

Begin

For i:=n Downto k1+1 Do

For j:=1 To m Do x[i+1, j]:=x[i, j];

{Элементу столбца с номером j присваиваем

элемент этого же столбца, но из

предыдущей строки}

For j:=1 То m Do x[k1+1, j]:=0;

End;

Так как число строк меняется, то процедуру Print надо изменить. Она должна выводить указанное количест­во строк, начиная с первой:

Procedure Print1 (n1: Integer;

x: dmyarray);

Var i, j: Integer;

Begin

For i:=1 To n1 Do

Begin

For j:=1 To m Do Write(x[i, j]: 4);

Writeln;

End;

End;

Часть основной программы будет такой:

Begin

Init(A);

Print(n, A);

Writeln ('Введите номер строки, после

которой надо вставить новую строку');

Readln(k);

Insert(k, A);

Print1(n+1, A);

Readln;

End.

Примечания

1. Если необходимо вставить новую строку после строки, удовлетворяющей некоторому условию, то надо лишь найти номер этой строки и задача сведется к решению уже рас­смотренной.

2. Если надо вставлять новые строки после всех строк с заданным условием, то надо учесть это при описании масси­ва. Заметим, что удобнее просматривать строки с последней и ввести счетчик вставленных строк.

3. Вставка новой строки перед строкой с номером k изме­нится только тем, что сдвигать назад надо не с (k+1)−й стро­ки, а с k−й.

4. Если надо вставлять столбцы, то размерность массива увеличивается по столбцам, а все остальное практически не меняется: надо сдвинуть столбцы вправо и на данное место записать новый столбец.

Удаление строки

Пример

Удалить строку с номером k.

Решение

Дли того чтобы удалить строку с номером k, необходимо:

· Сдвинуть все строки, начиная с данной на одну вверх.

· Последнюю строку "обнулить", то есть всем эле­ментам последней строки присвоить значение 0.

Описание массивов оставим прежним (размером nxm). Также в программе будем использовать процеду­ру вывода Print1 из предыдущего параграфа. Будем выводить на экран сначала все строки, а второй раз, после удаления, на одну меньше. Теперь опишем процеду­ру удаления строки с данным номером:

Program Example_123;

Procedure Delete (k1: Integer;

Var x: dmyarray);

Var i, j: Integer;

Begin

For i:=k1 To n-1 Do

For j:=1 To m Do

x [i, j]:=x[i+1, j];

For j:=1 To m Do x[n, j]:=0;

End;

Примечания

1. Задачу удаления строки, удовлетворяющей заданному условию, можно решить этим же способом, достаточно толь­ко найти ее номер.

2. Используя данную процедуру, можно решить еще одну задачу − удаление всех строк, которые обладают некоторым свойством.

Наши рекомендации