SICP_Python版第三章:递归与迭代

原创 2016年08月31日 11:42:13

这一章的开头讲了两种递归的方式,树状和线性。其实就是原版SICP第一章讲过的。

(1)书上给出了一个很精巧的程序用来描述一个过程,这个过程将树状递归的函数通过空间换时间的方式改写成一个线性递归的结构。

这段代码的精巧之处在于,通过f参数来绑定原来的递归函数。然后通过memo函数的返回值将原来递归函数的名字绑定在memorized这个函数上面。这样一旦调用f,它内部的两个fib就不再调用本身,而是调用新的memoized函数。这就构造出了一个非常奇特的现象:fibfibfib

另外,为了通用性,可以将参数改成一个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 memoized
fib = 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))
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

迭代和递归(Python)--乘方、最大公约数、汉诺塔、斐波那契、回文字符串

1.迭代 def iterPower(base,exp): result=1.0 while exp>0: result*=base exp-=1 ...

王亟亟的Python学习之路(六)-递归,迭代,列表生成式

转载请注明出处:王亟亟的大牛之路最近事情比较多,也没什么时间学习。(借口,明明在偷懒) 难得空下来,就继续把文章写下去。(玩手游时间更多)在贴今天要写的内容之前还是先说一下某些概念!(概念还是很重要...

python2 递归与迭代的效率问题

最近发现了一个叫51nod的编程网站,正好也学习了python2 于是就用Python2语言练练手,顺便也复习一下算法问题。 在期间做了一个1002数塔问题,引出了我对递归和迭代的效率问题,题目是这...

DNS递归和迭代

  • 2012年02月28日 22:51
  • 611KB
  • 下载

【问题】:进制转化算法(迭代版&递归版)

进制转化算法(迭代版&递归版)

递归和迭代两种方式实现归并排序(Java版)

递归版package MergeSort;import Utils.SortUtils; /** * 归并排序递归版 * @author liguodong */public class Dem...

归并排序(递归实现和迭代实现)

//首先是递归实现的方式#include #define MAXSIZE 10 //实现归并,并把数据都放在list1里面 void merging(int *list1,int list1_si...

二叉树遍历(递归与迭代)

二叉树遍历算法分为前序(PreOredr),中序(InOrder),后序(PostOrder)遍历。并且可以设计递归型或者迭代型算法。         本文二叉树定义为: struct Binary...

深究递归和迭代的区别、联系、优缺点及实例对比

深究递归和迭代的区别、联系、优缺点及实例对比 1.概念区分 递归的基本概念:程序调用自身的编程技巧称为递归,是函数自己调用自己. 一个函数在其定义中直接或间接调用自身的一种方法,它通常把一个大型...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SICP_Python版第三章:递归与迭代
举报原因:
原因补充:

(最多只允许输入30个字)