Вывод последовательности/массива "ёлочкой", "пирамидой" -- пример решения (вложенные циклы)
Primary tabs
Пусть у нас есть задача:
Выведите его на экран "ёлочкой" последовательности чисел до $N$.
Например для $N=12$ вы должны получить:1 2 3 4 5 6 7 8 9 10 11 12 ......
Эту задачу можно решить используя два подхода:
- Просто перебрать (обойти) массив (а в данном случае просто последовательность) так как мы это делаем для вывода элементов в строчку, но в определённые моменты выводить между элементами знак переноса строки и таким образом получить ёлочку.
- Рассмотреть ёлочку как таблицу из нескольких строк (их может быть и очень много) в которой каждая следующая строка длиннее предыдущей на $1$, а первая по своей длине $=1$.
Решение с циклом одного уровня
В этом подходе мы просто перебираем все числа до $n$ в цикле for, в каждом витке выводя очередное значение + иногда перенося строку:
var n, i, j, k:integer;
begin
writeln('vvedite chislo N:');
readln(n); // получаем число, до которого будем выводить ёлочку
k:=1; // число символов которые можно вывести не перенося строку
j:=0; // сколько мы вывели с последего переноса строки
for i:=1 to N do
begin
write(i, ' '); // просто выводим в ждом витке
j := j + 1; // учтём, что мы вывели ещё один символ (для будущего переноса)
if (j>=k) then // не пора ли переносить строку?
begin
writeln(); // перенос строки
j:=0; // в новой строке ёлочки мы ещё ничего не вывели (сбрасываем счетчик)
k:=k+1; // следубщий раз выведем на 1 символ больше до переноса строки
end;
end;
readln();
end.
Решение через вложенные циклы
Здесь мы рассмотрим код, иллюстрирующий второй подход:
Рассмотреть ёлочку как таблицу из нескольких строк (их может быть и очень много) в которой каждая следующая строка длиннее предыдущей на $1$, на первая по своей длине $=1$.
Ясно, что в таблице может быть сколько угодно строк (внешний цикл) + нам потребуется выводить каждую строку посимвольно (внутренний цикл).
При этом внешний цикл просто запускает вывод очередной строки и ничего не знает о том как именно эти строки выводятся -- его задача состоит просто в том, чтобы контролировать диапазон значений и заново запускать цикл вывода строки.
Очередной внутренний цикл вывода строки начинает свою работу с того значения $i$, на котором он остановился предыдущий раз. Поэтому мы инкрементируем $i$ в единственном месте -- а именно сразу после вывода на экран очередного значения.
Итак, решение №2:
var n, i, j, k:integer;
begin
writeln('vvedite chislo N:');
readln(n); // получаем число, до которого будем выводить ёлочку
i:=1;
k:=1;
while (i<=n) do // просто контролируем диапазон
begin
<h2></h2>
for j:=1 to k do // вывод очередной строки
begin
if (i<=n) then // если мы всё ещё в диапазоне
begin
write(i, ' '); // выводим очередное значение (с пробелом)
i:=i+1; // готовим следующее
end else
break; // досрочный выход из цикла
end;
writeln(); // переносим строку
k:=k+1; // следующая строка будет длиннее на 1 символ
end;
readln();
end.
Массив как источник данных
Безусловно, мы можем использовать в качестве источника данных для ёлочки и одномерный массив (в программе для инициализации его случайными числами используется процедура -- решим задачу первым способом без вложенных циклов с одним источником данных):
var n, i, j, k:integer;
a: array [1..17] of integer;
// процедура заполнит массив случайными числами
procedure initRandArray(var a: array of integer);
var min, max, i: integer;
begin
randomize(); // инициал. датчик случайных чисел (вызов стандартной процедуры)
min := -5; // левая граница
max := 10; // правая граница
{ обходим переданный массив
и инициализируем массив случайными числами}
for i:=low(a) to high(a) do
a[i] := random(max + abs(min)) + min;
end;
begin // начало тела программы
N := 17; // число элементов массива
initRandArray(a); // передаём по ссылке для заполнения случаными числами
k:=1; // число символов которые можно вывести не перенося строку
j:=0; // сколько мы вывели с последего переноса строки
for i:=1 to N do
begin
write(a[i], ' '); // выводим очередной элемент массива
j := j + 1; // учтём, что мы вывели ещё один символ (для будущего переноса строки)
if (j>=k) then // не пора ли переносить строку?
begin
writeln(); // перенос строки
j:=0; // в новой строке ёлочки мы ещё ничего не вывели (сбрасываем счетчик)
k:=k+1; // следубщий раз выведем на 1 символ больше до переноса строки
end;
end;
readln();
end.
- Log in to post comments
- 14098 reads