将尾递归/迭代过程转换为完全递归过程

时间:2014-01-20 10:22:27

标签: recursion scheme tail-recursion

我目前正在使用Scheme编写一个简单的程序,它可以递归地添加数字而不使用+运算符。现在我有这个程序可以做我想做的事情:

(define (add1 x) (+ x 1))

(define (sub1 x) (- x 1))

(define (plus x y) 
  (if (zero? y)
      x
      (plus (add1 x) (sub1 y))
      )
  )

然而,我的导师要求我放弃尾递归/迭代并完全递归地写加号过程。在没有告诉我太多的情况下(毕竟这是一次Uni练习),你能指出我正确的方向来弄清楚如何做到这一点吗?

提前致谢!

1 个答案:

答案 0 :(得分:2)

我赞同这些评论,这是一个愚蠢的练习 - 你的答案非常好,它已经是一个tail-recursive解决方案,它比教师要求的解决方案更有效(这也是递归的,但不是 tail 递归。调用完全递归是一种误称)。无论如何,这是一个暗示:

(define (plus x y)
  (if (zero? y) ; the first part remains unchanged
      x
      <???>))   ; now, what do we put here?

您必须在每个递归步骤中add1,我们的想法是您要准确1次添加y次,最后将其添加到x。让我用一个例子来说明这一点,添加43我们这样做:

(plus 4 3)

扩展到此:

(add1 (plus 4 2))
(add1 (add1 (plus 4 1)))
(add1 (add1 (add1 (plus 4 0))))
(add1 (add1 (add1 4)))

在上文中,4在开始时与x3绑定到y,在执行程序后,我们看到add1是我们第一次将1添加到4,然后1添加到5,最后1添加到6,直到我们获得7。换句话说:递归步骤必须将add1调用递归调用plus的结果,其中x保持不变,y递减一个单位,直到它达到零,此时我们到达基本情况,递归展开返回正确的结果。