PHP - Project Euler#2

时间:2011-02-28 22:33:33

标签: php

我的答案很好,但是当我运行以下代码时,


$total = 0;
$x = 0;

for ($i = 1;; $i++)
{
    $x = fib($i);

    if ($x >= 4000000)
        break;
    else if ($x % 2 == 0)
        $total += $x;

    print("fib($i) = ");
    print($x);
    print(", total = $total
"); } function fib($n) { if ($n == 0) return 0; else if ($n == 1) return 1; else return fib($n-1) + fib($n-2); }

我收到的警告是我超过了30秒的最长执行时间。你能给我一些关于如何改进这个算法的指针,或者关于代码本身的指针吗?顺便提一下,问题出现了here

4 个答案:

答案 0 :(得分:1)

假设$ i等于13.然后$x = fib(13)

现在在下一次迭代中,$i等于14$x = fib(14)

现在,在下一次迭代$i = 15中,我们必须计算$x$x必须等于fib(15)。现在,wat是计算$x最便宜的方法吗?

(我试图不给出答案,因为这会破坏这个难题)

答案 1 :(得分:1)

试试这个,在fib

中添加缓存
<?

$total = 0;
$x = 0;

for ($i = 1;; $i++) {
    $x = fib($i);

    if ($x >= 4000000) break;
    else if ($x % 2 == 0) $total += $x;

    print("fib($i) = ");
    print($x);
    print(", total = $total\n");
}

function fib($n) {
    static $cache = array();
    if (isset($cache[$n])) return $cache[$n];

    if ($n == 0) return 0;
    else if ($n == 1) return 1;
    else {
        $ret = fib($n-1) + fib($n-2);
        $cache[$n] = $ret;
        return $ret;
    }
}

时间:
真正的0m0.049s
用户0m0.027s
sys 0m0.013s

答案 2 :(得分:-1)

您可以更好地存储运行总计并在算法结束时将其打印出来。

您还可以简化您的fib($ n)函数,如下所示:

function fib($n)
{
    if($n>1)
      return fib($n-1) + fib($n-2);
    else
      return 0;
}

这将减少您需要经历的条件数量。

**现在编辑我重新阅读了问题**

答案 3 :(得分:-1)

如果您真的想要随意打印,请使用输出缓冲区。在开始时使用:

ob_start();

并且在执行完毕后,使用

ob_flush();
    flush();

你也可以用

增加你的超时
set_time_limit(300); //the value is seconds... so this is 5 minutes.