我想在数组上使用递归函数来解决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: 项目list3:
我在主程序中使用函数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步(在state1和状态2之间):无论函数的递归方面如何,每次有参数交换时,列表都由函数DisplayLists
显示,但状态2显示两个元素已被移动(从list2到list3的一个元素然后从list1到list2的一个元素)。这对我来说是一个很大的谜。
我有任何人都知道为什么它的工作原理我会感激不尽!
你的逻辑很好,你的问题也是出于同样的原因。
您错过的是您的DisplayLists
函数按发送给她的订单和全局名称打印列表。我会解释:
正如你在第一个问题中提到的那样,在调用MovePlates(1,list1,list3,list2)
中你用0调用其他MovePlates
我们可以忽略 - 但是你调用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个数字被移动......
希望有所帮助!
我只需要使用密钥为不同的列表指定一个名称来跟踪它们:
$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 完成: 其他:
不是很好看,但问题解决了。