求斐波那契数列
代码如下
from time import time
def fib(num): #普通解法
a, b = 1, 1
for i in range(num-2):
a, b = a + b, a
return a
def fib1(num, result={1: 1, 2: 1}):
try:
return result[num] #若所需要的第i个斐波那契数在字典中就直接输出
except KeyError:
#result[num] = fib1(num-1) + fib1(num-2) #用于直接求第i个斐波那契数
result[num] = result[num-1] + result[num-2]
return result[num]
def fib2(num, result={1: 1, 2: 1}):
if num <= len(result):
return result[num]
else:
result[num] = result[num-1] + result[num-2]
return result[num]
def fib3(num):
n, a, b = 0, 0, 1
while n < num:
a, b = b, a+b
n += 1
yield b
if __name__ == '__main__':
start1 = time()
for i in range(1, 5000):
fib(i)
end1 = time()
for i in range(1, 50000):
fib1(i)
end2 = time()
for i in range(1, 50000):
fib2(i)
end3 = time()
for i in fib3(50000):
pass
end4 = time()
print('暴力解法用时:%.18f' % (end1 - start1))
print('动态规划解法用时:%.18f' % (end2 - end1))
print('不使用异常的动态规划解法用时:%.18f' % (end3 - end2))
print('生成器解法用时:%.18f' % (end4 - end3)
运行结果:
求阶乘:
def fac(num, result={1: 1, 2: 2}):
if num <= len(result):
return result[num]
else:
result[num] = num * result[num-1]
return result[num]
for i in range(1, 200):
print(fac(i))
可以看出异常和if else的速度差不多。动态规划是用空间换时间,将子问题的答案放到空间里,如果后续有相同的子问题就可以直接从空间中得到结果,节省了时间,这就是使用动态规划解决重复子问题。
不过生成器更快,生成器可以节省内存,每次运行都只运行到yield处并return一个值,保存现场,再次运行生成器整个函数时再从yield处继续运行,内容不变,所以不占用内存,尤其在输出斐波那契数时。
关于生成器关键字yield:
https://blog.youkuaiyun.com/mieleizhi0522/article/details/82142856