如何在PHP中的递归函数中保存原始参数?

时间:2009-08-14 05:00:20

标签: php recursion

我正在使用PHP解决Euler问题。到目前为止我有这个功能:

<?php
$biggest = 0;
$counter = 1;
function test($i){
    global $biggest;
    global $counter;
    if ($i == 1) {
        echo "I'm done! Took me $biggest steps";
    }
    else {
        if ($i%2 == 0) {
            $counter = $counter + 1;
            if ($counter>$biggest) {
                $biggest = $counter;
            }
            test($i/2); 
        }
        else {
            $counter = $counter + 1;
            if ($counter>$biggest) {
                $biggest = $counter;
            }
            test(3*$i+1);
        }
    }
} 

test(13);
?>

我的问题大多是舔,但我似乎无法回到原来的输入。问题是“当你有一个数字,如果奇数得到3n + 1,当偶数,得到n / 2,做到直到返回1.什么起始值产生最多”步骤“才能到达一个?”我目前正在返回步数,但是当我递归时我会继续重置$ i,因此我无法记录开始#产生的最大步数。

如何跟踪该数字,但是在下一个循环实例中也没有销毁它? (我最终将它包装在for($ i = 1,$ i&lt; 1000000,$ i ++)循环中)

谢谢!

3 个答案:

答案 0 :(得分:2)

一种常见的方法是每次都传递原始参数,这样当你最终到达你的基本情况时,你仍然可以使用它。一个原始的(几乎完全不相关的例子):

<?php

function fact($n) {
    if($n == 1) return 1;
    else return $n * fact($n - 1);
}

?>

这是PHP中的阶乘函数的一个非常基本的实现。现在说你想出于任何原因想要在最后一步中获得初始值:你要构建一个包含fact($n)的包装函数memory_fact($n, $initial)

<?php

function fact($n) {
    return memory_fact($n, $n);
}

function memory_fact($n, $initial) {
    if($n == 1) return 1;
    else return $n * memory_fact($n - 1, $initial);
}

?>

这样,memory_fact始终知道它的起始位置。

答案 1 :(得分:0)

这很简单,只需将其作为参数传递即可!这是一些python-ish伪代码:

def func(start, arg):
    if foo(arg):
        return func(start, arg+1)
    else:
        return [start, arg]

答案 2 :(得分:0)

你不需要全局变量;全局是邪恶的。尝试从test()返回有用的内容。此外,您会发现上面的test()浪费了很多周期。尝试使用memoization

以下是计算斐波那契数的记忆示例:

function fib($n) {
    static $data = array(1, 1);
    if (!isset($data[$n])) {
        $data[$n] = fib($n-1) + fib($n-2);
    }
    return $data[$n];
}

请注意,还有其他时间效率恒定空间方法来处理Fibonacci数(包括O(log n)时间中的一个),但Collat​​z猜想有点棘手。