отображение массива в рекурсивной функции в php - PullRequest
0 голосов
/ 17 сентября 2018

Я хочу использовать рекурсивную функцию для массивов, чтобы решить проблему Ханойских Башен в php.Программа не выполняет то, что я ожидал, и после нескольких часов попыток выяснить, почему, кажется, я не смогу сделать это самостоятельно.

Мой index.php имеет следующий код:

    <!doctype HTML>
    <html>

     <head>
        <?php require"hanoi.php" ?>

        <title>Tours de Hanoi</title>
        <style>
            <?php
                if (isset($_POST['nbDiscs']))
                {
                    $nb = $_POST['nbDiscs'];
                }
            ?>
        </style>
    </head>

    <body>
        <h3>Tower of Hanoi</h3>

        <form action="index.php" method="post">
            <input type="text" name="nbDiscs" value=""/>
            <input type="submit" value="submit"/>
        </form>

        <?php
            if (isset($_POST['nbDiscs']))
            {
                $list1 = [];
                $list2 = [];
                $list3 = [];

                for($i=0;$i<$nb;$i++)
                {
                    array_push($list1, $i);
                }

                DisplayLists($list1,$list2,$list3);
                MovePlates($nb,$list1,$list2,$list3);

            }
        ?>
    </body>
    </html>

И мой hanoi.php файл следующий:

    <?php
        function MovePlates ($number, &$start, &$finish, &$other) {
            if ($number != 0) 
            {
                MovePlates($number-1, $start, $other, $finish);
                array_push($finish, array_pop($start));
                DisplayLists($start,$finish,$other);
                MovePlates($number-1, $other, $finish, $start);
            }       
        }

        function DisplayLists($list1,$list2,$list3)
        {
            echo"list1: ";
            for($i=0;$i<sizeof($list1);$i++) echo"$list1[$i]";
            echo"<br/>";
            echo"list2: ";
            for($i=0;$i<sizeof($list2);$i++) echo"$list2[$i]";
            echo"<br/>";
            echo"list3: ";
            for($i=0;$i<sizeof($list3);$i++) echo"$list3[$i]";
            echo"<br/>";
            echo"<hr/>";
        }
    ?>

Когда я запускаю это для 2 элементов, я получаю следующее:

list1: 01песни2:песни3:list1: 0list2: 1песни3:песни1:list2: 0list3: 1песни1:list2: 01песни3:

Я использую функцию DisplayLists в основной программе, поэтому я вижу состояние массива перед использованием функции.Давайте назовем это состояние 0.

Первая проблема

Я не понимаю, что происходит с первым шагом (переход от состояния 0 к состоянию 1), глядя нафункция «MovePlates»:

мы вызываем MovePlates (2, list1, list2, list3),

number = 2, поэтому мы вводим блок «if», тогда мы вызываем MovePlates(1,list1,list3,list2)

число = 1, поэтому мы входим в блок «если», тогда мы вызываем MovePlates(0,list1,list2,list3)

число = 0, чтобы функция ничего не делала, и мы продолжаем разрешать вызов число = 1.

Итак, вызов был MovePlates(1,list1,list3,list2), и теперь мы переходим к обмену элементами, что означает, что мы берем последний элемент списка1 и помещаем его в последнюю позицию списка 3.

Но, как вы можете видетьэто list2, который получает элемент (состояние 1).Я не понимаю, это похоже на то, что программа сохраняет аргументы в порядке первоначального вызова.

Вторая проблема

У меня нет постоянного шага 2 (между состоянием 1 и состоянием 2): независимо от рекурсивного аспекта функции, каждый раз, когда происходит обмен аргументами, списки отображаются функцией DisplayLists, но состояние 2 показывает, что два элемента были перемещены (один элемент из списка 2 вlist3 затем один элемент из list1 в список 2).Для меня это большая загадка.

У меня есть кто-нибудь, кто понимает, почему это работает, я был бы благодарен!

Ответы [ 2 ]

0 голосов
/ 17 сентября 2018

Мне просто нужно присвоить имя различным спискам, используя клавишу для отслеживания их:

    $list1['name'] = start;
    $list2['name'] = finish;
    $list3['name'] = other;

и записать их имя в моей функции отображения:

    function DisplayLists(&$list1,&$list2,&$list3)
        {
            echo $list1['name']." : ";
            for($i=0;$i<sizeof($list1)-1;$i++) echo"$list1[$i]";
            echo"<br/>";
            echo $list2['name']." : ";
            for($i=0;$i<sizeof($list2)-1;$i++) echo"$list2[$i]";
            echo"<br/>";
            echo $list3['name']." : ";
            for($i=0;$i<sizeof($list3)-1;$i++) echo"$list3[$i]";
            echo"<br/>";
            echo"<hr/>";
        }

тогда я получаю:

начало: 01Конец :Другой :начало: 0другое: 1Конец :Начните :конец: 0другое: 1Другой :финиш: 01Начните :

Не очень хорошо выглядит, но проблема решена.

0 голосов
/ 17 сентября 2018

Ваша логика в порядке, и обе ваши проблемы вызваны одной и той же причиной.

Что вы пропустили, так это то, что ваша функция DisplayLists печатает список по порядку, отправленному ей, и по глобальному имени.Я объясню:

Как вы упомянули в первой проблеме, в вызове MovePlates(1,list1,list3,list2) вы вызываете другие MovePlates с 0, которые мы можем игнорировать - но затем вы вызываете DisplayLists($start,$finish,$other); -> обратите внимание, что сейчас list3 = finish и list2 = other.Поэтому, когда вы вызываете DisplayLists, вы на самом деле вызываете DisplayLists(list1, list3, list2) таким образом, печать выглядит странно -> вы печатаете список 3, но пишете перед ним список 2. Фактическое состояние списков:

list1: 0
list2: 
list3: 1

Относительноу вас следующая проблема;после последнего объяснения мы можем видеть состояние 1, как упомянуто выше.Итак, теперь состояние 2:

list1: 
list2: 0
list3: 1

имеет смысл - перемещено только 1 число ...

Надеюсь, это поможет!

...