如何编写递归方案代码的迭代版本

时间:2016-10-02 14:44:46

标签: scheme racket

(define (g-sum f a b)
  (if (= a b)
      (f b)
      (+ (f b) (g-sum f a (- b 1)))))

我不知道如何更改它以便它可以迭代。

2 个答案:

答案 0 :(得分:0)

见SICP的练习1.30。比尔在这里有一个解决方案。

http://www.billthelizard.com/2010/04/sicp-exercise-130-iterative-sums.html

答案 1 :(得分:0)

你可以试试这个:

(define (g-sum f a b)
  (let loop ((acc 0) (b b))
    (if (< b a)
        acc
        (loop (+ (f b) acc) (- b 1)))))

将递归过程转换为迭代过程的技巧是传递一个累积结果的参数并在递归结束时返回它,确保递归调用是我们在递归步骤中做的最后一件事,没有计算待定。

为了简单起见,我使用了名为let,但这不是必需的,因为使用帮助程序内部过程会产生相同的效果。上面的代码相当于:

(define (g-sum f a b)
  (define (loop acc b)
    (if (< b a)
        acc
        (loop (+ (f b) acc) (- b 1))))
  (loop 0 b))

如果您仍然无法掌握上述代码,请记住,只要我们传递所需的参数,就可以将内部帮助程序作为单独的过程提取出来。关键是,你需要一个额外的参数用作累加器,你如何做到这一点是无关紧要的,我个人更喜欢使用一个名为let的人。这相当于我之前的两个解决方案:

(define (g-sum f a b)
  (loop f a b 0))

(define (loop f a b acc)
  (if (< b a)
      acc
      (loop f a (- b 1) (+ (f b) acc))))