问题描述
所以我不确定我是否终于理解了它,或者我还是错了。正确吗?
(define (add-one x)
(+ x 1))
(define (sub-one x)
(- x 1))
(define (add-numbers x y)
(if (zero? y)
x
(add-numbers (add-one x) (sub-one y))))
(define (add-numbers2 x y)
(if (zero? y)
x
(add-numbers2 (+ x 1) (- y 1))))
... add-numbers2 是一个递归过程又是一个迭代过程吗?
解决方法
两者在语法上都是递归的,但是两者都生成迭代的计算过程。在第一个功能中:
(define (add-numbers x y)
(if (zero? y)
x
(add-numbers (add-one x) (sub-one y))))
然后,如果y
不为零,则发生的事情是该事物需要评估(add-numbers (add-one x) (sub-one y))
,并且为此需要调用(add-one x)
和(add-one y)
,然后对两个结果调用add-numbers
,整个函数的结果就是对add-numbers
的调用返回的结果。重要的是,对add-numbers
的调用是最后发生的 last 事件。无需返回到执行该函数调用的时间点,因为除了返回计算出的值之外,无需执行其他任何操作。这意味着该过程是迭代的。
在第二个版本中:
(define (add-numbers2 x y)
(if (zero? y)
x
(add-numbers2 (+ x 1) (- y 1))))
好吧,最简单的方法是发现+
和-
是 just函数,所以这是完全一样的!唯一的区别是+
和-
恰好是实现定义的功能,而不是您定义的功能。
这是一个真正描述递归计算过程的版本:
(define (add-numbers3 x y)
(if (zero? y)
x
(+ 1 (add-numbers3 x (- y 1)))))
在此版本中,如果y
不为零,则该函数必须在x
上调用自身,并从y
减去1的结果...并且 then ,完成后,仍然需要在该调用的结果中加1。因此,它需要保留一个内存,其中有此未完成的操作加1,然后在从该函数调用返回时实际执行该加法。使用您的原始功能可能更容易看到这一点:
(define (add-numbers4 x y)
(if (zero? y)
x
(add-one (add-numbers4 x (sub-one y)))))
现在您可以清楚地看到,对add-numbers4
的递归调用返回时,还有更多工作要做。
@tb解释了两个过程都是迭代的,这是正确的。我们可以将过程可视化为-
(add-numbers 3 5)
(add-numbers 4 4)
(add-numbers 5 3)
(add-numbers 6 2)
(add-numbers 7 1)
(add-numbers 8 0)
8
看看它如何保持平稳?这是一个 linear 过程。只需进行微小的修改,我们就可以产生一个完全不同的过程-
(define (add-numbers x y)
(if (zero? y)
x
(+ 1 (add-numbers x (- y 1))))
请注意,随着过程计算相关值,过程将如何加深,直到最终崩溃为返回值为止。这是一个递归过程-
(add-numbers 3 5)
(+ 1 (add-numbers 3 4))
(+ 1 (+ 1 (add-numbers 3 3)))
(+ 1 (+ 1 (+ 1 (add-numbers 3 2))))
(+ 1 (+ 1 (+ 1 (+ 1 (add-numbers 3 1)))))
(+ 1 (+ 1 (+ 1 (+ 1 (+ 1 (add-numbers 3 0))))))
(+ 1 (+ 1 (+ 1 (+ 1 (+ 1 3)))))
(+ 1 (+ 1 (+ 1 (+ 1 4))))
(+ 1 (+ 1 (+ 1 5)))
(+ 1 (+ 1 6))
(+ 1 7)
8