#practice26:缓存与装饰器(递归子问题)
对于需要重复计算子问题的情况,可以使用缓存,缓存实现有两种方式:1.在函数内定义某种数据结构存储数据 2.使用装饰器(闭包结构)
菲波那切数列为:1,1,2,3,5,8,13;即从第三项开始,每一项为前两项之和。
以菲波那切数列为例
1、一般的实现方式为:
#求第n项的斐波那契数,从0开始
def fibonacci(n):
if n <= 1:
return 1
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(33))
上述函数中由于需要重复计算某些项,所以计算速度非常缓慢,如果在计算过程中能保存一些中间值,速度提升非常明显
2、使用缓存:保存中间值
#方法一:缓存法
#cache以值None层层传递到最底层,然后创建空字典
#cache逐层传递引用,每层的变量cache均指向同一对象!
def fibonacci(n,cache=None):
if cache is None:
cache = {}
if n in cache.keys():
return cache[n]
if n <= 1:
return 1
cache[n] = fibonacci(n-1,cache) + fibonacci(n-2,cache)
return cache[n]
print(fibonacci(33))
这种储存中间值的方法不太直观
3、 使用装饰器,利用闭包保存中间值
#方法二:使用装饰器,一来不改变函数形式,二可利用闭包保存变量状态,比缓存法容易理解
def decorator(f):
cache = {}
def wrapper(*args,**kargs):
if args not in cache.keys():
cache[args] = f(*args,**kargs)
return cache[args]
return wrapper
@decorator
def fibonacci(n):
if n <= 1:
return 1
return fibonacci(n-1) + fibonacci(n-2)
pri