Вывод последовательности/массива "ёлочкой", "пирамидой" -- пример решения (вложенные циклы)
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
- 13460 reads