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))
版权声明:本文为博主原创文章,未经博主允许不得转载。

用递归,迭代,通项公式三种方法实现斐波那契数列求解

斐波那契数列指的是这样一个数列:1、1、2、3、5、8、13、21、……    这个数列从第三项开始,每一项都等于前两项之和。它的通项公式为:(1/√5)*{[(1+√5)/2]^n -[(1-√5...
  • no_coffee_no_love
  • no_coffee_no_love
  • 2014年08月04日 11:08
  • 1837

【数据结构与算法】深入浅出递归和迭代的通用转换思想

递归和递归的深入浅出 一般来说,能用迭代的地方就不要用递归!理论上讲,所有的递归和迭代之间都能相互转换! (一)何为迭代?首先我们来看下面这段简单的代码:int sum(int n ) { ...
  • terence1212
  • terence1212
  • 2016年06月05日 11:36
  • 2163

迭代是人,递归是神(迭代与递归的总结:比较)

在计算机编程实现中有常常两种方法:一曰迭代(iterate);二曰递归(recursion)。 从“编程之美”的角度看,可以借用一句非常经典的话:“迭代是人,递归是神!”来从宏观上对二者进行...
  • LG1259156776
  • LG1259156776
  • 2015年07月12日 13:55
  • 6524

python实现斐波那契数列:迭代和递归对比

迭代和递归从概念上讲,递归就是指程序调用自身的编程思想,即一个函数调用本身;迭代是利用已知的变量值,根据递推公式不断演进得到变量新值得编程思想。...
  • wuu1299
  • wuu1299
  • 2018年01月02日 14:10
  • 29

python2 递归与迭代的效率问题

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

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

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

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

1.迭代 def iterPower(base,exp): result=1.0 while exp>0: result*=base exp-=1 ...
  • u013232740
  • u013232740
  • 2015年07月23日 15:24
  • 1183

DNS递归和迭代

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

DNS转发器,根提示,递归,迭代的差别

  • 2016年03月31日 16:43
  • 41KB
  • 下载

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

递归版package MergeSort;import Utils.SortUtils; /** * 归并排序递归版 * @author liguodong */public class Dem...
  • scgaliguodong123_
  • scgaliguodong123_
  • 2015年07月26日 21:43
  • 2477
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SICP_Python版第三章:递归与迭代
举报原因:
原因补充:

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