方案:过程是递归的,但是过程是递归的还是迭代的?

问题描述

所以我不确定我是否终于理解了它,或者我还是错了。正确吗?

(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