为什么这段代码的执行时间会超过30S

2013-12-25 03:46:31 +08:00
 kennedy32
function tuzi($x){
if($x == 0 || $x == 1){
return 1;
}else{
return tuzi($x-1)+tuzi($x-2);
}
}
function testtuzi($n){
for ($i=0;$i<=$n;$i++){
echo "兔子在".$i."月的数目是".tuzi($i)."<br/>";
}
}
testtuzi(60);
6345 次点击
所在节点    PHP
46 条回复
Rojey
2013-12-25 04:04:06 +08:00
递归,循环太多,循环套递归,递归套循环。能不慢么。
casparchen
2013-12-25 04:17:09 +08:00
远大于2的60次方次计算,30S就能出结果?不会吧。
能出结果已经很不错了。
skyangel3
2013-12-25 04:55:43 +08:00
60的fibonnaci sequence 运算30s 在php可以出结果。你的机器已经很牛了
goodan
2013-12-25 08:54:07 +08:00
@skyangel3 是飞播纳妾数列咩…
wizardoz
2013-12-25 09:17:05 +08:00
你用的这个算法是算法导论上用来做反面教材的。
justfindu
2013-12-25 09:20:06 +08:00
这递归到死了吧
kennedy32
2013-12-25 09:37:11 +08:00
@Rojey
@casparchen
@skyangel3

虚拟主机跑到35行,自己的电脑还没试过。我以为是个小运算,很简单的加法。
kennedy32
2013-12-25 09:37:37 +08:00
@wizardoz 正确的是怎样?
ccidcce32167
2013-12-25 09:38:14 +08:00
建议你用银河或深蓝来跑这个程序
luoyou1014
2013-12-25 09:39:46 +08:00
@kennedy32
改用循环写菲波纳锲算法
kennedy32
2013-12-25 09:50:02 +08:00
@luoyou1014 可以把一楼的代码改写一下么??
zencoding
2013-12-25 09:55:44 +08:00
@kennedy32 这个是一个经典的死递归,从代码层次改变不了多少效率的
Keita1314
2013-12-25 10:18:51 +08:00
@kennedy32 用数组别用递归
*a= 1;
*(a+1) =1;
for(int i =2;i<=n;i++)
*(a+i) = *(a+i-1)+*(a+i-2);
luoyou1014
2013-12-25 10:19:49 +08:00
@kennedy32

<?php
function tuzi($x){
$sum = 0;
$first=0;
$second=1;
for($i=0;$i<$x;$i++){
$sum = $first + $second;
$first = $second;
$second = $sum;
}
return $sum;
}

function testtuzi($n){
for ($i=0;$i<=$n;$i++){
echo "兔子在".$i."月的数目是".tuzi($i)."<br/>";
}
}
testtuzi(60);
levn
2013-12-25 10:25:29 +08:00
TMBest
2013-12-25 10:30:00 +08:00
算法概论第一章吧,就在讲fib的各种算法,更快的算法是用矩阵。最快的是这货:
long int fib(unsigned long int n) {
return lround((pow(0.5 + 0.5 * sqrt(5.0), n) -
pow(0.5 - 0.5 * sqrt(5.0), n)) /
sqrt(5.0));
}
参考:http://www.evanmiller.org/mathematical-hacker.html#HN_Repost
tonitech
2013-12-25 10:40:00 +08:00
return tuzi($x-1)+tuzi($x-2);
这句话让你的代码变成了一个庞大的2叉树。。。n进去就是2的n-1次方!
Golevka
2013-12-25 10:43:05 +08:00
因为这种二阶线性递归式直接写出来的话复杂度是exponential time的, 如果一定要递归的话可以用memoization. 所以说那些妄想速成码农就应该尽早砍掉重练, 回去撸一撸SICP和lambda calculus就知道踏实了.

ref: http://mitpress.mit.edu/sicp/full-text/sicp/book/node16.html
moondark
2013-12-25 10:45:07 +08:00
@TMBest 这货也只是理论上的最快,前提是sqrt与pow函数的运行时间较短
clippit
2013-12-25 10:47:20 +08:00
@TMBest 这个是直接套通项公式了吧?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/94455

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX