10

在 SICP第 1.2.1 节中,作者在下面给出了这样一个代码示例来展示如何使用迭代过程来解决阶乘问题:

(define (factorial n)
  (fact-iter 1 1 n))
(define (fact-iter product counter max-count)
  (if (> counter max-count)
      product
      (fact-iter (* counter product)
                 (+ counter 1)
                 max-count)))

并说“我们将诸如 fact-iter 之类的递归过程称为生成迭代过程似乎令人不安。但是,该过程实际上是迭代的:它的状态完全由它的三个状态变量捕获,解释器需要跟踪只有三个变量才能执行该过程。”

我不明白作者的意思。递归过程和递归过程有什么区别?为什么他说下面的递归过程生成了一个迭代过程?

4

1 回答 1

17

递归过程需要在递归调用进行时维护调用者的状态。例如,如果你写:

(define (fact-recurse n)
  (if (< n 2)
      1
      (* n (fact-recurse (- n 1)))))

外部调用必须记住n并等待内部调用返回,然后才能执行乘法运算。如果您调用(fact-recurse 10),当函数到达其递归结束时,将有 9 个堆叠乘法待处理。

但在迭代过程中,可以丢弃较早的状态。这在示例代码中是可能的,因为所需的所有信息都作为递归调用中的参数传递。不再需要外部调用中的变量,因此不需要将任何内容保存在堆栈中。

由于不再需要外部调用的参数,因此可以将递归调用转换为赋值:

(set! product (* counter product))
(set! counter (+ counter 1)
(set! max-count max-count)

然后它只是跳到程序的开头。

于 2013-06-22T19:33:38.000 回答