我们有以下代码:
import time
def rec1(len):
if( len < 2): return 1;
return 2*rec1(len-1);
def rec2(len):
if( len < 2): return 1;
return rec2(len-1) + rec2(len-1);
def callAndReport(len, method):
time1 = time.time()
answer = method(len)
time2 = time.time()
print("{0} with {1}:{2} in {3:.0f} ms".format(len,method.__name__,answer, (time2-time1)*1000))
if __name__ == '__main__':
callAndReport(20,rec1)
callAndReport(20,rec2)
print('')
callAndReport(23,rec1)
callAndReport(23,rec2)
此代码生成以下输出:
20 with rec1:524288 in 0 ms
20 with rec2:524288 in 642 ms
23 with rec1:4194304 in 0 ms
23 with rec2:4194304 in 4613 ms
有人可以解释执行时间的差异吗?我想的很少,但我想确定。
为了完整性,我遇到的原始问题是下面的方法(可以很容易地表达为for循环,但这不是重点):
def find11s_rec(len):
if len<2: return 0
if len== 2: return 1;
return find11s_rec(len-2)+find11s_rec(len-1)+2**(len-2)
答案 0 :(得分:5)
这是因为rec1
仅使用rec1
一次,rec2
使用rec2
两次。然后,那些内部 rec2
调用将每次调用rec2
两次。函数调用的数量将呈指数级增长。虽然rec1
可能会使用x
来电,但rec2
会使用2^x
来电。在计算机科学术语中,rec1
是O(x),而rec2
是O(2 ^ x)。在更复杂的情况下,危险的递归可能是不明显的;所以使用调试器来找出实际完成的内容。
答案 1 :(得分:2)
rec1
的复杂度为O(n),rec2
的复杂度为O(2 ^ n)。这是一个巨大的性能差异。
rec2(n) = rec2(n-1) + rec2(n-1)
= (rec2(n-2) + rec2(n-2)) + (rec2(n-2) + rec2(n-2)) = 4 * rec2(n-2)
...
rec2(n) = (2^n)*rec2(1)
= O(2^n)