2009-08-14 91 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