2009-08-14 34 views
0

我在PHP中处理欧拉问题。我至今这个功能:如何将原始参数保存在PHP的递归函数中?

<?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 < 1000000,$ i ++)循环中)

谢谢!

回答

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总是知道它在哪里开始。

0

这很简单,只需将它作为参数传递即可!下面是一些蟒蛇上下的伪代码:

def func(start, arg): 
    if foo(arg): 
     return func(start, arg+1) 
    else: 
     return [start, arg] 
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]; 
} 

注意,有处理斐波那契数(包括一个在O(log n)的时间),其他时间efficent恒定空间的方法,但Collat​​z猜想有点棘手。

+1

功能上的静态并不比全局变量好,真的。 – jason 2009-08-14 05:43:08