Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Гладков_Кулютникова.doc
Скачиваний:
8
Добавлен:
03.11.2018
Размер:
1.36 Mб
Скачать

Двумерные массивы

Двумерный массив (матрица) можно рассматривать как одномерный массив, каждый элемент которого сам является одномерным массивом. Поэтому для работы с элементами двумерного массива нужно организовать два цикла. Каждый из них отвечает за перебор значений соответствующего индекса. Для двумерного массива можно использовать те же схемы перебора, что и для одномерного, но комбинаций здесь будет в два раза больше.

При таком подходе двумерный массив может быть описан следующим образом:

var a: array [1..n] of array [1..m] of real; {массив а, состоящий из n элементов

каждый элемент которого - одномерный массив из m действительных чисел}

В этом случае обратиться к элементу массива можно следующим образом: a[i][j].

Чаще используется следующее описание двумерного массива:

var a: array [1..n, 1..m] of real;

А к элементу массива обращаются следующим образом: a[i, j], где i - номер строки, j - номер столбца.

Следует заметить, тип индекса строки и столбца могут быть различны. Например, массив, описывающий наличие фигур на шахматной доске, может быть представлен следующим образом:

var a: array [1..8,‘a’..’h’] of boolean;

Количество элементов двумерного массива определяется путем перемножения количества столбцов на количество строк.

В Паскале разрешены многомерные массивы. Глубина вложенности массивов произвольная, поэтому количество элементов в списке индексов (размерность массива) не ограничена, однако суммарная длина внутреннего представления любого массива не может быть больше 65 520 байт.

В памяти элементы массива следуют друг за другом так, что при переходе от младших к старшим адресам, наиболее быстро меняется самый правый индекс массива.

Обрабатывать элементы двумерного массива можно как по строкам, так и по столбцам.

{обработка по строкам}

for i := 1 to n do {перебор строк}

for j := 1 to m do {перебор столбцов}

{обработка a[i, j]};

{обработка по столбцам}

for j := 1 to m do {перебор столбцов}

for i := 1 to n do {перебор строк}

{обработка a[i, j]};

В первом варианте перебираться будут следующие элементы (для случая n = 3, m = 4): a[1, 1], a[1, 2], a[1, 3], a[1, 4], a[2, 1], a[2, 2], a[2, 3], a[2, 4], a[3,1], a[3, 2], a[3, 3], a[3, 4], a[4, 1], a[4, 2], a[4, 3], a[4, 4].

Во втором варианте: a[1, 1], a[2, 1], a[3, 1], a[4, 1], a[1, 2], a[2, 2], a[3, 2], a[4, 2], a[1,3], a[2, 3], a[3, 3], a[4, 3], a[1, 4], a[2, 4], a[3, 4], a[4, 4].

Для двумерных массивов справедливы те же классы задач, что и для одномерных, но схемы перебора организуются с помощью двух циклов. Для решения задач на двумерные массивы нужно знать некоторые соотношения для индексов. Рассмотрим двумерный массив a размерностью 55.

a11 a12 a13 a14 a15 Элементы: а11, а22, а33, а44, а55 составляют главную диагональ.

a21 a22 a23 a24 a25 Для них справедливо равенство номеров строки и столбца (i=j).

a31 a32 a33 a34 a35 Элементы: а51, а42, а33, а24, а15 составляют побочную диагональ.

a41 a42 a43 a44 a45 Для них справедливо равенство i+j=n+1.

a51 a52 a53 a54 a55

Для элементов, расположенных выше главной диагонали, справедливо i < j, для элементов ниже главной диагонали - i > j. Для элементов, расположеных на линиях, параллельных главной диагонали, справедливо следующее соотношение: |i-j| = k, где k - номер линии по отношению к главной диагонали.

Для элементов, расположенных выше побочной диагонали, справедливо: i+j<n+1, а для элементов ниже побочной диагонали: i+j>n+1. Индексы элементов, расположенных на линиях, параллельных побочной диагонали, удовлетворяют соотношению: 2  i+j  2*n.

Задача 1. Сформируйте массив указанного вида:

1)

2)

3)

4)

Решение.

Вариант 1. Сначала необходимо весь массив заполнить нулями, затем первую и последнюю строку, первый и последний столбец заполнить единицами.

for i := 1 to n do

for j := 1 to n do

a[i, j] := 0;

for i := 1 to n do

begin

a[1, i] := 1; {первая строка}

a[n, i] := 1; {последняя строка}

a[i, 1] := 1; {первый столбец}

a[i, n] := 1; {последний столбец}

end;

В варианте 2 заполняются единицами элементы главной и побочной диагонали.

for i := 1 to n do

for j := 1 to n do

a[i, j] := 0;

for i := 1 to n do

(i= j ) or (i + j = n + 1) then a[i, j] := 1;

В варианте 3 можно выделить два треугольника: верхний и нижний. В верхнем треугольнике с увеличением номера строки уменьшается количество элементов, равных 1, причем для 2-ой строки единицами заполняются элементы со второго до n - 1, т.е. каждый раз индекс столбца слева и справа уменьшается на 1. В нижнем треугольнике при уменьшении номера строки уменьшается индекс столбца справа и слева на 1.

for i := 1 to n do

for j := 1 to n do

a[i, j] := 0;

for i := 1 to n div 2 do

for j := i to n - i + 1 do

a[i, j] := 1;

for i := n downto n div 2 + 1 do

for j := n - i + 1 to i do

a[i, j] := 1;

В варианте 4 также рассмотрим два треугольника. В верхнем треугольнике при увеличении номера строки количество столбцов должно увеличиваться влево и вправо на 1. В нижнем треугольнике - уменьшаться.

for i := 1 to n do или for i := 1 to n do

for j := 1 to n do for j := 1 to n do

a[i, j] := 0; a[i, j] := 0; k := 1;

for i := 1 to n div 2 + 1 do for j := n div 2 downto 1 do

for j := n div 2 - i + 2 to n div 2 + i do for i := k + 1 to n - k do

a[i, j] := 1; a[i, j] := 1; k := 0;

for i := n downto n div 2 + 2 do for j := n div 2 + 1 to n do

for j := i - n div 2 to n -(i- n div 2) + 1 do for i := k + 1 to n - k do

a[i, j] := 1; a [i, j] := 1;

Вывод двумерного массива удобно оформлять в виде таблицы. Для этого необходимо после печати очередной строки массива не забывать делать перевод на новую строку.

for i := 1 to n do

begin

writeln;

for j := 1 to m do

write(a[i, j], ‘ ‘);

end;

Задача 2. Дан двумерный массив nm. Сформируйте одномерный массив, содержащий количество нулей: а) в соответствующей строке двумерного массива; б) в соответствующем столбце массива.

В варианте а) необходимо организовать перебор элементов массива по строкам, при этом не забывать обнулить переменную, накапливающую количество нулей, перед обработкой каждой строки. Аналогичным образом решается задача для варианта б) с той лишь разницей, что обработка должна осуществляться по столбцам.

Вариант а).

const nn = 20; mm = 30;

var a: array [1..nn, 1..mm] of real;

b: array [1..nn] of integer; {количество нулей в соответствующей

строке}

i, j, n, m: integer;

begin

write (‘задайте количество строк и столбцов’);

readln (n, m);

writeln (‘заполните массив’);

for i := 1 to n do

for j := 1 to m do

read (a[i, j]);

for i := 1 to n do

begin b[i] := 0; {количество нулей в i-ой строке равно нулю}

for j := 1 to m do

if a[i, j] = 0 then b[i] := b[i] + 1;

end;

for i := 1 to n do

write (b[i], ‘ ‘);

end.

Вариант б).

const nn = 20; mm = 30;

var a: array [1..nn, 1..mm] of real;

b: array [1..nn] of integer; {количество нулей в соответствующей

строке}

i, j, n, m: integer;

begin

write (‘задайте количество строк и столбцов’);

readln (n, m);

writeln (‘заполните массив’);

for i := 1 to n do

for j := 1 to m do

read (a[i, j]);

for j := 1 to m do

begin b[j] := 0; {количество нулей в j-ом столбце равно нулю}

for i := 1 to n do

if a[i, j] = 0 then b[i] := b[i] + 1;

end;

for i := 1 to m do

write (b[i], ‘ ‘);

end.

Задача 3. В заданном двумерном массиве переставьте строки и столбцы таким образом, чтобы максимальный элемент оказался в верхнем левом углу.

Решение. Сначала необходимо найти максимальный элемент, а точнее его координаты по i и по j, назовем их соответственно imax и jmax. Затем необходимо сначала поменять местами первую и imax-ую строки, затем первый и jmax-ый столбцы.

const nn = 20; mm = 30;

var a: array [1..nn, 1..mm] of real;

i, j, imax, jmax, n, m: integer;

r: real;

begin

write (‘задайте количество строк и столбцов’);

readln (n, m);

writeln (‘заполните массив’);

for i := 1 to n do

for j := 1 to m do

read (a[i, j]);

imax := 1; jmax := 1; {считаем верхний левый элемент кандидатом на

максимум}

for i := 1 to n do

for j := 1 to m do

if a[i, j] > a[imax, jmax]

then begin imax := i; jmax := j end;

for j := 1 to m do {меняются местами 1-ая и imax-ая строки}

begin r := a[1, j];

a[1, j] := a[imax, j];

a[imax, j] := r

end;

for i := 1 to n do {меняются местами 1-ый и jmax-ый столбцы}

begin r := a[i, 1];

a[i, 1] := a[i, jmax];

a[i, jmax] := r

end;

for i := 1 to n do

begin

writeln;

for j := 1 to m do

write (a[i, j], ‘ ‘);

end.

Задача 4. Поменяйте местами элементы относительно главной диагонали, при этом строки и столбцы меняются местами.

Решение. Этот процесс называют транспонированием матрицы. Если исходная матрица была вида:

После преобразования

Видно, что элементы главной диагонали остались неизменны, а элементы aij поменялись местами с элементами aji.

for i := 1 to n do

for j := 1 to n do

if i < j do

begin r := a[i, j];

a[i, j] := a[j, i];

a[j, i] := r

end;

Упражнения.

1. Провели опрос n человек (n - нечетное) по m вопросам. На вопросы предполагались ответы “Да” или “Нет”. “Популярным” ответом на любой вопрос считался тот, который встретился больше, чем в половине случаев. Проверьте, имеется ли среди опрошенных человек, все ответы которого “популярны”.

2. Заданы результаты опроса n человек на m вопросов. На вопросы предполагались ответы “Да” и “Нет”. Для каждого вопроса напечатайте строчку, состоящую из крестиков и ноликов. Вначале печатаются все крестики, затем все нолики. Количество крестиков равно количеству ответов “Да”, а количество ноликов - количеству ответов “Нет”.

3. В городе П. есть m банков. Известны величины задолженностей банков друг другу. Укажите банки с максимальным долгом.

4. В двумерном массиве записаны по m оценок n школьников. Укажите номера школьников, средняя оценка которых больше 4.5.

5. Имеются результаты конкурса на знание иностранных слов у школьников. Представьте эту информацию в виде, удобном для обработки на компьютере, и напечатайте фамилии школьников, которые знают глаголов в два раза больше, чем существительных.

6. Задан двумерный массив, содержащий случайные числа от -15 до 24. Напечатайте массив в виде строк звездочек, количество которых в каждой строке равно сумме элементов в соответствующей строке массива. Ось х располагается вертикально.

7. Задана информация об n книгах. О каждой книге известно количество страниц и среднее количество букв на каждой странице. Представьте эту информацию в виде, удобном для обработки на компьютере, и найдите номера книг, количество информации в которых находится между 12 Мб и 16 Мб.

8. Укажите все ошибки в Паскаль-программе:

program PR;

const if := 35;

fi := if - 15;

tipe arr = array [fi...if] of integer;

var a: {массив} fi;

i, n, j: int{индексы и количество элементов}eger;

begin write (‘Введите’, n);

read (n);

for i := 1 to n - 1 do

begin read (a[i])

for j := i + 1 downto n do

if a(i) > a(j) and i > j

then a(i) = a(j);

i := if;

while i <= n do write (a[i], ‘ ‘);

end

Все ли найденные Вами ошибки обнаружит транслятор?

9. Восстановите пропущенные операторы и элементы выражений Паскаль-программы (они обозначены ?) так, чтобы она решала задачу: “Нечетные строки матрицы заменить вектором”. Опишите назначение всех переменных. Сколько строк будет выведено на экран по окончании работы программы?

?

type mas1 = array [?..?] of integer; { ? }

mas2 = array [?..?] of ?; { ? }

var x: mas1; { ? }

w: mas2; { ? }

n: integer; { ? }

i: integer; { ? }

j: integer; { ? }

begin write (‘Введите ?’);

readln (n);

writeln (‘Введите ?’);

for i := 1 to n do

begin write (‘Введите’, ?, ‘-й элемент вектора ’);

?

end;

{первоначальное заполнение матрицы единицами}

?

?

{Решение задачи}

for i := 0 to n div 2 do w[?] := x;

{Вывод результатов}

for i := 1 to n do

begin ?;

for j := 1 to n do write (w[i, j], ‘ ‘)

end;

end.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]