【问题标题】:array display in recursive function in phpphp中递归函数中的数组显示
【发布时间】:2019-02-20 20:49:27
【问题描述】:

我想在数组上使用递归函数来解决 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
list2:
list3:


list1: 0
list2: 1
list3:

list1:
list2: 0
list3: 1

list1:
list2: 01
列表3:

我在主程序中使用了函数DisplayLists,所以在使用函数之前我可以看到数组的状态。我们称之为状态 0。

第一个问题

我不明白第一步(从状态 0 到状态 1)发生了什么,查看“MovePlates”功能:

我们调用 MovePlates(2,list1,list2,list3),

number = 2,所以我们输入“if”块然后我们调用MovePlates(1,list1,list3,list2)

number = 1,所以我们进入“if”块然后我们调用MovePlates(0,list1,list2,list3)

number = 0 所以该函数什么都不做,我们继续解析 number=1 调用。

所以调用是MovePlates(1,list1,list3,list2),我们现在去元素交换,这意味着我们把list1的最后一个元素放到list3的最后一个位置。

但正如您所见,获取元素的是 list2(状态 1)。 我不明白,这就像程序将参数保持在初始调用的顺序中一样。

第二个问题

我不明白第 2 步(在状态 1 和状态 2 之间):无论函数的递归方面如何,每次交换参数时,列表都由函数 DisplayLists 显示,但状态 2 显示两个元素已被移动(一个元素从列表 2 到列表 3,然后一个元素从列表 1 到列表 2)。这对我来说是一个很大的谜。

如果有人知道它为什么会这样工作,我将不胜感激!

【问题讨论】:

    标签: php arrays recursion pass-by-reference


    【解决方案1】:

    您的逻辑很好,并且您的两个问题都是由相同的原因引起的。

    您错过的是您的DisplayLists 函数按发送给她的订单和全局名称打印列表。我会解释:

    正如您在第一个问题中提到的那样,在调用 MovePlates(1,list1,list3,list2) 时,您使用 0 调用其他 MovePlates,我们可以忽略 - 但随后您调用 DisplayLists($start,$finish,$other); -> 请注意,现在 list3 = finishlist2 = other。所以当你调用DisplayLists 你实际上调用DisplayLists(list1, list3, list2) 这样打印看起来很奇怪-> 你打印列表 3 但在它之前写列表 2。列表的实际状态是:

    list1: 0
    list2: 
    list3: 1
    

    关于你的下一个问题;在最后一次解释之后,我们可以看到状态 1 如上所述。所以现在,状态 2:

    list1: 
    list2: 0
    list3: 1
    

    是有道理的 - 只移动了 1 个数字...

    希望有帮助!

    【讨论】:

    • 哦,我应该看到的。谢谢!
    【解决方案2】:

    我只需要使用一个键来为不同的列表分配一个名称来跟踪它们:

        $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
    开始:

    不是很好看,但问题解决了。

    【讨论】:

      猜你喜欢
      • 2010-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-27
      • 2017-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多