SICP_Python版第三章:递归与迭代
来源:互联网 发布:电子日历制作软件 编辑:程序博客网 时间:2024/06/06 01:04
这一章的开头讲了两种递归的方式,树状和线性。其实就是原版SICP第一章讲过的。
(1) 书上给出了一个很精巧的程序用来描述一个过程,这个过程将树状递归的函数通过空间换时间的方式改写成一个线性递归的结构。
这段代码的精巧之处在于,通过f参数来绑定原来的递归函数。然后通过memo函数的返回值将原来递归函数的名字绑定在memorized这个函数上面。这样一旦调用f,它内部的两个fib就不再调用本身,而是调用新的memoized函数。这就构造出了一个非常奇特的现象:在fib里面调用的fib不再是原本的fib。
另外,为了通用性,可以将参数改成一个tuple类型。
def fib(n): print('run f') if n == 1: return 0 if n == 2: return 1 return fib(n-2) + fib(n-1)#fib = memo(fib)改变了函数名def memo(f): """Return a memoized version of single-argument function f.""" cache = {} def memoized(*args): if tuple(args) not in cache: cache[tuple(args)] = f(*args) return cache[tuple(args)] return memoizedfib = memo(fib)
例子: 给定任意的钱a元,以及指定的零钱种类kinds={c1,c2…cn},求出可以换成零钱的方式。
1: 直接进行树状递归:考虑对于任何一种状态,可以拿第一种零钱来换,也可以不拿。那么问题就被分解成两个子问题。
def count_changes(a,kinds = (1,5,10,25,50)): if a==0:return 1 if a<0 or len(kinds)==0: return 0 return count_changes(a,kinds[1:])+count_changes(a-kinds[0],kinds)count_changes = memo(count_changes)
2 :
count_changes = memo(count_changes)
3 :迭代形式,相对比较难。需要仔细分析子问题和原问题的依赖关系。利用了动态规划的思想。在书里面留作一个问题.
def count_changes_iter(a,kinds=(1,5,10,25,50)): def solve(record,i,j): if i==0:return 1 if i<0 or j<=0:return 0 return record[i][j] m,n = a+1,len(kinds)+1 record = [[0]*(n+1) for i in range(m+1)] for k in range(0,m+n-1): for i in range(0,k+1): j = k-i if i >=m or j<0 or j>=n:continue if j!=0:d = kinds[n-j-1] else:d = a+1 record[i][j] = solve(record,i,j-1)+solve(record,i-d,j) return record[a][n-1]print(count_changes_iter(1000))
0 0
- SICP_Python版第三章:递归与迭代
- SICP_Python版第2章:递归的定义序列
- SICP_Python版第二章
- 迭代与递归
- 递归与迭代
- 递归与迭代
- 递归与迭代
- 递归与迭代
- 递归与迭代
- 递归与迭代
- 递归与迭代
- 递归与迭代
- 递归与迭代
- 递归与迭代
- 递归与迭代
- 递归与迭代
- 递归与迭代
- 递归与迭代
- Kafka分布式消息队列框架
- arrayList——list和arrayList区别
- VB是否过时?
- oracle数据库使用学习
- caffe的LMDB数据库输入数据类型由char改为float
- SICP_Python版第三章:递归与迭代
- 在linux下对接口进行Jmeter 压测
- JDBC连接数据库
- Java多线程同步设计中使用Mutex
- 工厂设计模式
- Android 侧边栏
- 教你使用HighCharts框架显示报表
- Android中的设计模式——观察者模式
- 内部和外部晶振区别