Пример решения. 9. Вывести на экран массив случайных чисел "ёлочкой"

Задача из этого списка

<?php
/*Задайте случайным образом массив из N элементов. 
 * Выведите его на экран "ёлочкой" */
function create_array ($n) // Создание массива случайных чисел 
{
    for ($i = 0; $i < $n; $i++) {
        $arr[$i] = rand(); 
    }
    return $arr;
}
function printer_tree ($tree) // Вывод "ёлочкой"
{
    $level_1 = array ($tree[0]); // Массив первой строки 
    echo $level_1[0], "<br>"; // печатается
    $tree = array_slice ($tree, 1); // и сокращает $tree на самого себя
    for ($j = 0; $j <= count($tree); $j++){
        for ($i = 0; $i <= count($level_1); $i++) { // Массив второй строки, равный длине первого массива +1
            $level_2[$i] = $tree[$i];
            echo $level_2[$i], " "; // печатается
	}
        $level_1 = $level_2;
        $tree = array_slice ($tree, count($level_2)); // и сокращает $tree на самого себя
        echo "<br>";
    }
}
$result = create_array(36);
foreach ($result as $k => $v) {
    echo $v, " ";
}
echo "<p>";
printer_tree($result);

Вроде заморочено, но получилось так.

Key Words for FKN + antitotal forum (CS VSU):

melisa's picture

с помощью переменной $n, считающей количество элементов новой строки

<?php
function create_array($m) // Создание массива случайных чисел 
{
    for ($i = 0; $i < $m; $i++) {
        $arr[$i] = rand(); 
    }
    return $arr;
}
function printer_tree($tree) // Вывод массива "ёлочкой"
{
    $n = 0;
    for ($i = 0; $i <= count($tree); $i++) {
        for ($j = 0; $j <= $n; $j++) {
            echo $tree[$j], " ";
        }
        $tree = array_slice($tree, $j);
        $n++;
        echo "<br>";
    }
}
$result = create_array(36);
foreach ($result as $k => $v) {
    echo $v, " ";
}
echo "<p>";
printer_tree($result);
vedro-compota's picture

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

_____________
матфак вгу и остальная классика =)

melisa's picture

альтернативное решение с помощью доп. переменных, считающих длину строки

<?php
/*Задайте случайным образом массив из N элементов. 
 * Выведите его на экран "ёлочкой" */
function create_array($m) // Создание массива случайных чисел 
{
    for ($i = 0; $i < $m; $i++) {
        $arr[$i] = rand(); 
    }
    return $arr;
}
function printer_tree($tree) // Вывод массива "ёлочкой"
{
    $n = 1; // Длина очередной строки
    $k = 0; // Длина печатаемой строки
    $i = 0; // 
    while ($i < count($tree)) {
        while ($k < $n) { 
            echo $tree[$i], " ";
            $k++;
            $i++;
        }
        echo "<br>";
        $n++;
        $k = 0;
    }
}
$result = create_array(38);
foreach ($result as $v) {
    echo $v, " ";
}
echo "<p>";
printer_tree($result);
vedro-compota's picture

хорошо, но:

  1. $n = 1; // Длина предыдущей строки

    -- скорее это всё же, "длина очередной строки" (неточный комментарий)

  2. Обычно если границы диапазона известны рекомендуюется использовать цикл for:
            while ($k < $n) { 
                echo $tree[$i], " ";
                $k++;
                $i++;
            }
    

    -- всё же забыть про изменение счетчика в for сложнее. (это, опять же, концептуальная рекомендация, ну и for использует меньше строк кода).

_____________
матфак вгу и остальная классика =)

melisa's picture

В данном случае использован цикл while с ручным счётом в связи с тем, что при каждом следующем обращении к вложенному циклу \$i должно иметь присвоенное ранее значение. Цикл for каждый раз обнуляет значение счётчика, а значит, в каждой новой строке будет печататься \$tree заново, с элемента [0].

vedro-compota's picture

Цикл for каждый раз обнуляет значение счётчика, а значит, в каждой новой строке будет печататься $tree заново, с элемента [0].

у вас счетчиком является k и вы его тоже обнуляете до начала вложенного цикла:

$k = 0;

-- т.е. вы вполне можете сделать цикл for с этим счетчиком.

_____________
матфак вгу и остальная классика =)

melisa's picture

for ($k = 0; $k < $n; $k++) { 
    if ($i < count($tree)) {
        echo $tree[$i], " ";
        $i++;
    }
    else {
        break;
    }
}
vedro-compota's picture

то есть вы добавили проверку:

if ($i < count($tree)) {

чтобы вовремя оборвать очередную выводимую строку ёлочки -- значит она была нужна и в цикле while.

Кстати, там выводится предупреждение о выходе за диапазон (именно по этой причине):

Notice</b>:  Undefined offset: 38 in <b>[...][...]</b> on line <b>18</b><br />

_____________
матфак вгу и остальная классика =)

Подправил немного первый вариант

<?php
/*Задайте случайным образом массив из N элементов. 
 * Выведите его на экран "ёлочкой" */
function create_array ($n) // Создание массива случайных чисел 
{
    for ($i = 0; $i < $n; $i++) {
        $arr[$i] = rand(1, 9) ; 
    }
    return $arr ;
}

function printer_tree ($tree) // Вывод "ёлочкой"
{
    $level=[]; // Массив "нулевой" строки
    
    for ($j = 0; $j <= count($tree); $j++) {

        $level = array_slice($tree, 0, count($level)+1);  // Массив второй строки, равный длине первого массива +1

        foreach ($level as $number) { // печатается "вторая" строка
            echo $number, " "; 
        }
      
        $tree = array_slice($tree, count($level)); // и сокращает $tree на длину выведенной строки
        echo "<br>";
    }
}
$result = create_array(38);
foreach ($result as $k => $v) {
    echo $v, " ";
}
echo "<p>";
printer_tree($result);

В обоих скриптах присутствует неточность. Если мы будем выводить массив из 38 элементов,
то последние два элемента этого массива не будут выведены.

melisa's picture

действительно, не выводятся первые два элемента каждой строки (начиная с 3-й), если за ними не следует вывод последующих элементов.

Достаточно изменить условие в одном цикле. Итерация будет выполнена, если в массиве есть числа для вывода.

<?php
/*Задайте случайным образом массив из N элементов. 
 * Выведите его на экран "ёлочкой" */
function create_array ($n) // Создание массива случайных чисел 
{
    for ($i = 0; $i < $n; $i++) {
        $arr[$i] = rand(1, 9) ; 
    }
    return $arr ;
}

function printer_tree ($tree) // Вывод "ёлочкой"
{
    $level=[]; // Массив "нулевой" строки
    
    for ($j = 0; 0 < count($tree); $j++) {

        $level = array_slice($tree, 0, count($level)+1);  // Массив второй строки, равный длине первого массива +1

        foreach ($level as $number) { // печатается "вторая" строка
            echo $number, " "; 
        }
      
        $tree = array_slice($tree, count($level)); // и сокращает $tree на длину выведенной строки
        echo "<br>";
    }
}
$result = create_array(38);
foreach ($result as $k => $v) {
    echo $v, " ";
}
echo "<p>";
printer_tree($result);
melisa's picture

Спасибо!