Вложенные циклы
Цель работы
Цель работы - приобретение навыков построения вложенных циклических алгоритмов и реализация с их помощью управляющих конструкций повторения.
Задани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) |
Все элементы массива или конец строки |
procedure TForm1.Button1Click(Sender: TObject);
Var Cod, 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]
if Cod <> 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;
Двумерные массивы
Двумерный массив можно рассматривать как одномерный, у которого каждый элемент сам является массивом, например,
type mat = array [0..5] of array [0..2] of Byte
Такое описание можно заменить более компактным:
type mat = array [0..5, 0..2] of Byte; это двумерный массив, у которого 6 строк [0..5] и 3 столбца [0..2].
Примеры описания двумерных массивов
cons t 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 - количество измерений) представляет собой динамический массив и, следовательно, нуждается в инициации.