斐波那契数列
1、斐波那契数列
def fib(n):
if n == 1 or n == 0:
return 1
else:
return fib(n-2)+fib(n-1)
print([fib(n) for n in range(10)])
输出结果:[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
2、如果改为40个数的斐波那契
from time import time
def fib(n):
if n == 1 or n == 0:
return 1
else:
return fib(n-2)+fib(n-1)
start = time()
print([fib(n) for n in range(40)])
end = time()
print("cost-time:{}".format(end-start))
运行结果:cost-time:131.5741560459137
光40位居然花费了131秒,50位就更长了.难是因为这个运算量太大了吗,NONONO,是因为我们算法没有经过优化.
-
看上面这张图,你会发现我们在计算兔子序列的时候,有大量重复的计算,比如算F(10)=F(9)+F(8),F(9)=F(8)+F(7),F(8)需要重复计算两次~~
-
怎么破,很容易想到我们需要用一个缓存,把这个计算过的数字存在一个表里面,用的时候若这个数字在这个表,就不用再花cpu去运算,直接取就好了。
我们现在构造一个缓冲区cache
我们查表,比如用字典来保存,比如cache[8]=34,我们只需要查一下8是不是在字典里面就可以了,在的话直接取,不在的话再去用算法计算,是不是很爽
from time import time
def fib(n, cache=None):
if cache is None:
cache = {}
if n in cache:
return cache[n]
if n == 1 or n == 0:
return 1
else:
cache[n] = fib(n-2, cache) + fib(n-1, cache)
return cache[n]
start = time()
print([fib(n) for n in range(40)])
end = time()
print("cost-time:{}".format(end-start))
运行结果:cost-time:0.0009999275207519531
看运行40项,几乎不费吹灰之力,这就是算法的魅力。
基于装饰器来实现
from time import time
def decorate(func):
cache = {}
def wraper(n):
if n not in cache:
cache[n] = func(n)
return cache[n]
return wraper
@decorate
def fib(n):
if n == 1 or n == 0:
return 1
else:
return fib(n - 2) + fib(n - 1)
start = time()
print([fib(n) for n in range(400)])
end = time()
print("cost-time:{}".format(end - start))
===============================================================
基于yield来实现更加简单、高效。
import time def fab(num): n, a, b = 0, 0, 1 while n < num: yield b a, b = b, a + b n += 1 start_time = time.time() yield_fab = list(fab(400)) stop_time = time.time() - start_time >>>print(yield_fab) [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610... >>>print(stop_time) 0.0039997100830078125

浙公网安备 33010602011771号