1.1斐波那契序列
1.1.1递归和基线条件的运用
def fib1(n:int) -> int:
if n < 2:
return n
return fib1(n - 1) + fib1(n - 2)
if __name__ == "__main__":
print(fib1(5))
print(fib1(6))
print(fib1(10))
1.1.2用结果缓存来救场
结果缓存(memoization)是一种缓存技术,即在每次计算任务完成后就把结果保存起来,这样下次需要时即可直接检索出结果,而不需要重复计算。
from typing import Dict
memo:Dict[int,int] = {0 : 0 , 1 : 1}
#利用字典对象作为结果缓存
def fib2(n:int) ->int:
if n not in memo:
memo[n]=fib2(n-1)+fib2(n-2)
return memo[n]
if __name__ == "__main__":
print(fib2(5))
print(fib2(50))
1.1.3自动化的结果缓存
Python 自带了一个内置的装饰器( decorator ),可以自动为任何函数缓存结果。每次用新的参数执行方法时,该装饰器就会把返回值缓存起来。以后再用相同的参数调用该方法时,都会从缓存中读取该参数对应的方法之前的返回值并返回。
from functools import lru_cache
@lru_cache(maxsize=None)
def fib3(n:int)->int:
if n<2:
return n
return fib3(n-2)+fib3(n-1)
if __name__ == "__main__":
print(fib3(5))
print(fib3(50))
@lru_cache的maxsize属性表示对所修饰的函数最多应该缓存多少次最近的调用结果,如果将其设置为None则表示没有限制。
1.1.4迭代法解决斐波那契问题
def fib4(n:int)->int:
if n == 0:return n
last:int=0
next:int=1
for _ in range(1,n):
last,next=next,last+next
return next
if __name__ == "__main__":
print(fib4(5))
print(fib4(50))
last 被设置为 next 的上一个值, next 被设置为 last 的上一个值加上 next 的上一个值。这样在 last 已更新而 next 未更新时,就不用创建临时变量以存储 next 的上一个值了。
1.1.5用生成器生成斐波那契数
用yield语句很容易就能把方法转换为Python生成器。在对生成器进行迭代时,每轮迭代都会用yield语句从斐波那契序列中吐出一个值。
from typing import Generator
def fib5(n:int)->Generator[int,None,None]:
yield 0
if n>0:yield 1
last:int=0
next:int=1
for _ in range(1,n):
last, next = next, last + next
yield next
if __name__ == "__main__":
for i in fib5(50):
print(i,end=" ")
if i%5==0:
print()