費波納切(Fibonacci)數列的前N項和公式(PHP版)三種算法的比較

大家都知道費波納切數列1,1,2,3,5,8,13(第三項是前兩項的和),它的通項公式爲:f(x)=f(x-1)+f(x-2),f(0)=0,f(1)=1

我們用PHP來求f(40)吧

 

方式一:

遞歸。最單純的遞歸。

function f($i)
{
if ($i==0) return 0;
if ($i==1) return 1;
return f($i-1) + f($i-2);
}
$start = microtime(true);
print f(40);            // 我的電腦,PHP超時了,還沒計算出來,估計是要2-3分鐘的
$end = microtime(true);
print $sum. ":" .($end-$start)."<BR>/n";

這個顯然是太慢了。

我們對方式一進行改進:

方式一的主要問題在於: 求f(y)的時候要去計算f(y-1) f(y-2)….直到f(3) f(2) (1) f(0), 在這個過程中,爲了計算出f(y-2) 的值,又要去重複計算f(y-3) f(y-4)…直到f(3) f(2) f(1) f(0) ,顯然有了太多的重複計算了。

那麼我們就加上緩存吧

$cache = array();
function f2($i)
{
global $cache;
if ($i==0) $cache[$i] = 0;
if ($i==1) $cache[$i] = 1;
 if (!isset($cache[$i]))  $cache[$i] = f2($i-1) + f2($i-2);
return $cache[$i];
}
$start = microtime(true);
print f2(40);   //0.000317096710205 秒
$end = microtime(true);
print $sum. ":" .($end-$start)."<BR>/n";

很牛了吧,速度提升了N個數量級。但是這還不是最快的。

你想一下,我們遞歸了多少次, f2 被調用了多少次?這次用循環試試看吧

 

方法三:

$a = 0;
$b = 1;
$start = microtime(true);
for ($i=0; $i<40;$i++)
{
$sum = $a+$b;
$b =  $a;
$a = $sum;
}
$end = microtime(true);
print $sum. ":" .($end-$start)."<BR>/n";   //2.59876251221E-5  秒

又快了一個數量級!

 

看來還是循環最快啊。

 

轉自:http://www.zhaokunyao.com/archives/154 感謝!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章