Динамические двумерные массивы

Вложенные циклы

Цель работы

Цель работы - приобретение навыков построения вложенных циклических алгоритмов и реализация с их помощью управляющих конструкций повторения.

Заданиe

1. Задайте массив M x N, выполните действия для Вашего варианта. Ввод массива вручную.

1 Найдите наибольший элемент, укажите его положение.

2 Найдите столбец с наибольшей суммой.

3 Найдите столбец с наименьшей суммой.

4 Найдите сумму элементов каждой диагонали.

5 Найдите строку с наибольшей суммой.

6 Найдите строку с наименьшей суммой.

2. Задайте таблицу M x N, выполните действия для Вашего варианта. Ввод данных вручную.

1 Найдите наибольший элемент, укажите его положение.

2 Найдите столбец с наибольшей суммой.

3 Найдите столбец с наименьшей суммой.

4 Найдите сумму элементов каждой диагонали.

5 Найдите строку с наибольшей суммой.

6 Найдите строку с наименьшей суммой.

Теоретические сведения

В качестве оператора в теле цикла можно использовать практически любой оператор, в том числе For, While, Repeat. Такие конструкции называют конструкциями с вложенными циклами. При выборе оператора повторений следует учитывать:

· оператор For применяют только при известном заранее количестве повторений;

· операторы While и Repeat управляют повторениями по логическому условию;

· оператор, находящийся в теле цикла Repeat, всегда будет выполнен минимум один раз;

· в зависимости от условия, оператор, находящийся в теле цикла While, может быть не выполнен ни разу.

Ниже приведены фрагменты алгоритмов с вложенными циклами.

Оператор
i=0..n
j=0..k
Цикл For с вложенным циклом For Forj=0 to k do {Внешний цикл} For i=0 ton do {Вложенный цикл} Оператор;  

i<=n
Оператор i:=i+1; I:=I+1
j<=k
j:=0;
i:=0;
j=j+1
Цикл While с вложенным циклом While   j:=0; Whilej<=k do {Внешний цикл} begin i:=0: While i<=n do {Вложенный цикл} begin Оператор; i:=i+1: end; {Конец вложенного цикла} j:=j=1; end;

i>n  
j:=j+1
j:=0;  
i:=0;
Оператор i:+i+1
j>k  
Repeat с вложенным циклом Repeat   j=0; Repeat i=0; repeat Оператор; i:=i+1; until i>n; j=j+1; Until j>k;    

j:=0
i=0..n  
Оператор
j:=j+1  
j>k
Repeat с вложенным циклом For     j:=j+1; Repeat for i:=0 to n do Оператор; j:=j+1; Until j>k;

Пример 1. Ручной ввод массива в поле TEdit

Дано:LabeledEdit1.Text – поле ввода в которое вручную введён массив как строка текста;

введённые значения соответствуют алфавиту вещественных чисел иразделены пробелами;

переменная Mx: T_M - динамический массив (T_M = array of Real); Label1.Caption - метка для вывода номера элемента массива i, и значения элемента массива Mx[i];

Требуется сформировать из данных поля ввода числовые значения массива Mx.

Постановка задачи.

· для выделения одного элемента массива из строки LabeledEdit1.Text, будем в цикле считывать по одному символы и вставлять их во вспомогательную строку S, пока не достигнем пробела, LabeledEdit1.Text[j] <> ' ')

· количество считанных символов фиксирует счётчик элементов текстовой строки j;

· количество сформированных строк фиксирует счётчик числового массива i;

· преобразуем вспомогательную строку S в элемент массива Val(S, Mx[i], Cod);

· эти действия будем повторять, пока количество считанных символов меньше или равно длине строки ввода, j <= Length(LabeledEdit1.Text.

True
false
Начало
Конец
Повторять: до пробела, i < длины строки  
true
While
Until
Exit
I=0, j=0 – обнуление счётчиков Очистка метки вывода, Label.Caption  
if
Недопустимый cимвол
Схема алгоритма. Ручной ввод массива procedure TForm1.Button1Click(Sender: TObject)
inc(j); увеличение j S:='' очистка вспомогательной строки  
к S присоединяется очередной символ Inc(j)
false
Val(S, Mx[i], Cod)
Cod <> 0
Очистка метки вывода
Вывод i Mx[i]
Inc(i)
Все элементы массива или конец строки

procedureTForm1.Button1Click(Sender: TObject);

VarCod, i, j : Integer; //Cod – индикатор преобразования Строка-Число;

// i – счётчик числового массива, j – счётчик элементов текстовой строки

S: String; //вспомогательная строка, для формирования очередного элемента

Begin

i:=0; J:=0; //обнуление счётчиков

Label1.Caption:= ''; //очистка метки вывода

Repeat//повторять, пока условие «Until ….» не станет true

inc(j); //увеличивает j на 1, при первом вхождении j=1

S:=''; //очистка вспомогательной строки

{Пока «очередной символ не пробел» и «счётчик j меньше или равен длине строки, повторять}

While(LabeledEdit1.Text[j] <> ' ') and (j <= Length(LabeledEdit1.Text))do

Begin

S:= S + LabeledEdit1.Text[j]; //к S присоединяется очередной символ

Inc(j); //j увеличился на 1, переход на новый виток цикла While

end;//конец While, в S символы одного элемента массива

Val(S, Mx[i], Cod);

//Преобразование символов S в элемент числового массива Mx[i]

ifCod <> 0 //контроль, если Cod =0 – преобразование успешное

then begin//ошибка преобразования

ShowMessage('Недопустимый символ!' );

Label1.Caption:= ''; //очистка метки вывода

exit; //досрочное завершение цикла Repeat

End;

{Преобразование было успешным. Далее вывод счётчика i, табуляция (#9), вывод элемента массива Mx[i], символы конца строки}

Label1.Caption:= Label1.Caption+

IntTostr(i)+#9+ FloatToStr(Mx[i])+#10#13;

inc(i); //увеличивает i на 1

{Если i < старшего индекса массива или j < длины строки цикл Repeat продолжать}

Until(i>High(Mx))or(j> Length(LabeledEdit1.Text)); //конец цикла Repeat

End;

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

Двумерный массив можно рассматривать как одномерный, у которого каждый элемент сам является массивом, например,

typemat =array [0..5]of array [0..2]ofByte

Такое описание можно заменить более компактным:

typemat = array[0..5, 0..2]of Byte; это двумерный массив, у которого 6 строк [0..5] и 3 столбца [0..2].

Примеры описания двумерных массивов

const N=4; K=3;

type Vector = array [1..N, 1..K ] of Real; //тип массив 4х3}

var M_X : Vector; //переменная массив 4х3}

M_Y : array [1.N, 0..K ] of Byte; //переменная массив 4х4}

M_Z : array [ 1..4, 3..7 ] of Word;

В памяти элементы многомерного массива следуют друг за другом так, что при переходе от младших адресов к старшим наиболее быстро меняется правый индекс массива. Например, для двумерного массива А:array [1..3,1..3]of Byte, последовательность расположения элементов будет следующая:

A[1,1] A[1,2] A[1,3] A[2,1] A[2,2] A[2,3] A[3,1] A[3,2] A[3,3]

Динамические двумерные массивы

При объявлении таких массивов границы индексов не указывают:

var В:array of array of Real; //двумерный массив

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

SetLength(var S; NewLength: Integer) - устанавливает длину переменной динамического массива,

где S - переменная динамического массива;

NewLength - число элементов массива S, нижняя граница индексов

динамического массива всегда 0.

Для освобождения памяти занятой массивом достаточно присвоить идентификатору значение nil или использовать процедуру Finalize.

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

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