SICP中的迭代因子过程

时间:2016-02-10 08:56:23

标签: recursion scheme lisp factorial sicp

这是SICP的一个生成递归过程的阶乘过程。

(define (factorial n)
  (if (= n 1) 
      1 
      (* n (factorial (- n 1)))))

现在这是相同的过程,但会生成一个迭代过程。计数器增加到n,并且产品在每个过程调用中通过计数器自行增加。当不在块结构中时,fact-iter具有变量max-count,实际上是n。

(define (factorial n)
  (define (iter product counter)
    (if (> counter n)
        product
        (iter (* counter product)
              (+ counter 1))))
  (iter 1 1))

我有点好奇为什么我们需要反击,除了增加自身并使用其值来测试基本情况之外它并没有做任何事情。与递归过程一样,我们只是在添加累加器以使其迭代时才执行相同的过程吗?例如:

(define (factorial n) 
(define (fact-iter product n)
  (if (= n 1)
      product
      (fact-iter (* n product)
                 (- n 1))))
  (fact-iter 1 n))

所以,这仍然是一个迭代过程,我认为这个过程比第一个例子更明显。

然而,这本书首先要提到第一个例子。那么第一个迭代示例优于第二个过程的优势是什么?

1 个答案:

答案 0 :(得分:5)

您的两个迭代版本是相同的,除了一个计数并与自由变量n进行比较,而另一个倒计时并与常量进行比较。

它在速度上没有太大的区别,所以我想你应该选择一个更清晰的意图。有些人可能更喜欢上升的步骤。

有时你可以明智地选择顺序。如果您要编制一个数字列表,那么您可以选择与您想要的结果列表相反的顺序的步骤,以便能够保持迭代:

(define (make-range to)
  (define (aux to acc)
    (if (> 0 to)
        acc
        (aux (- to 1) (cons to acc))))
  (aux to '()))

(define (make-reverse-range start)
  (define (aux n acc)
    (if (> n start)
        acc
        (aux (+ n 1) (cons n acc))))
  (aux 0 '()))

(make-range 10)          ; ==> (0 1 2 3 4 5 6 7 8 9 10)
(make-reverse-range 10)  ; ==> (10 9 8 7 6 5 4 3 2 1 0)