这是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))
所以,这仍然是一个迭代过程,我认为这个过程比第一个例子更明显。
然而,这本书首先要提到第一个例子。那么第一个迭代示例优于第二个过程的优势是什么?
答案 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)