我目前正在使用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练习),你能指出我正确的方向来弄清楚如何做到这一点吗?
提前致谢!
答案 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
。让我用一个例子来说明这一点,添加4
加3
我们这样做:
(plus 4 3)
扩展到此:
(add1 (plus 4 2))
(add1 (add1 (plus 4 1)))
(add1 (add1 (add1 (plus 4 0))))
(add1 (add1 (add1 4)))
在上文中,4
在开始时与x
和3
绑定到y
,在执行程序后,我们看到add1
是我们第一次将1
添加到4
,然后1
添加到5
,最后1
添加到6
,直到我们获得7
。换句话说:递归步骤必须将add1
调用递归调用plus
的结果,其中x
保持不变,y
递减一个单位,直到它达到零,此时我们到达基本情况,递归展开返回正确的结果。