我有一个算法来查找foods
数组的所有唯一组合。如果任何组合符合我们的calories value
,那么它应该返回true。
这是我的方法:
<?php
$food = [
['a', 70],
['b', 5],
['c', 20],
['d', 10]
];
function eat($calories, $food, $k = 0, $p = []) {
for ($i=$k; $i < count($food); $i++) {
$r = array_merge($p, [$i]);
$c = 0;
foreach ($r as $j) {
$c += $food[$j][1];
}
if ($c == $calories) {
echo "success";
return true;
}
eat($calories, $food, $i+1, $r);
}
}
var_dump(eat(100, $food));
?>
问题是:为什么这段代码输出&#39;成功&#39;但是没有回归呢?
以下是在线执行:
答案 0 :(得分:1)
您正在递归调用该函数。转储的值将是第一次调用的返回值,因为您忽略其他调用的返回值。
在这里,您似乎只需要成功拨打一个电话,之后该功能必须终止。因此,您可以检查是否成功,如果已经发生,则返回true,以防止函数更进一步,并告诉调用者(这可能是第一次调用,或递归中的任何其他调用)调用成功。< / p>
<?php
$food = [
['a', 70],
['b', 5],
['c', 20],
['d', 10]
];
function eat($calories, $food, $k = 0, $p = []) {
for ($i=$k; $i < count($food); $i++) {
$r = array_merge($p, [$i]);
$c = 0;
foreach ($r as $j) {
$c += $food[$j][1];
}
if ($c == $calories) {
echo "success";
return true;
}
if(eat($calories, $food, $i+1, $r))
return true;
}
}
var_dump(eat(100, $food));
?>
答案 1 :(得分:1)
您调用的原始函数永远不会返回true,后面调用的函数会返回true到它的&#34; parent&#34;,但是true永远不会返回给原始调用者。修复方法如下:
if (eat($calories, $food, $i+1, $r)) {
return true;
}
这将检查递归函数返回的内容,以及true
是否再次返回true
答案 2 :(得分:1)
对递归数组函数略有不同的看法是使用内置函数arrayIterator。
$food = array(
'a'=> 70,
'b'=> 5,
'c'=> 20,
'd'=> 10,
'e'=> 99
);
function eat( $calories, $food, $p=array() ){
$a = new ArrayObject( array_merge( $food, $p ) );
$iterator = $a->getIterator();
while( $iterator->valid() ) {
if( $iterator->current()==$calories ) {
echo 'success: key='.$iterator->key().' value='.$iterator->current();
return true;
}
$iterator->next();
}
return false;
}
eat( 120, $food, array( 'banana'=>500,'apple'=>120 ) );