Python 两次调用该方法时尾部递归的解释
让我们看看下面的代码:Python 两次调用该方法时尾部递归的解释,python,python-3.x,Python,Python 3.x,让我们看看下面的代码: 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
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)
有人能解释一下执行时间差吗?我没有什么想法,但我想确定一下
为了完整性,我最初的问题是下面的方法,它可以很容易地表示为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)
因为rec1只使用rec1一次,而rec2使用rec2两次。然后这些内部rec2调用将分别调用rec2两次。函数调用的数量将以指数形式增加。rec1可能使用x个调用,而rec2将使用2^x个调用。在计算机科学术语中,rec1是Ox,而rec2是O2^x。在更复杂的情况下,危险的递归可能是无效的;因此,请使用调试器找出实际执行的操作。rec1的复杂性为On,而rec2的复杂性为O2^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)
rec2有所谓的重叠子问题-您正在重复已经完成的工作。尾部递归也不是,这不需要对递归调用的结果执行任何操作。哈!太明显了。我没有想到在随后的通话中会出现“分支”。2^x现在已清除。
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)