【问题标题】:Turn tail-recursive/iterative procedure into a fully recursive procedure将尾递归/迭代过程转变为完全递归过程
【发布时间】:2014-01-20 10:22:27
【问题描述】:

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

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

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

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

但是,我的导师要求我放弃尾递归/迭代,并编写完全递归的 plus 过程。不用告诉我太多(这毕竟是一个 Uni 练习),你能指出我正确的方向来弄清楚如何去做吗?

提前致谢!

【问题讨论】:

  • 如果不想尾递归,只需要移动add1,但我不会说在哪里。 (add1如何使用+?我很确定它确实如此。)
  • 告诉你的导师尾递归是“完全递归”的。
  • 这是我听过的最愚蠢的练习。

标签: recursion scheme tail-recursion


【解决方案1】:

我同意 cmets,这是一个愚蠢的练习 - 你的答案很好,它已经是一个 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一开始是绑定x3绑定到y,执行程序后我们看到add1被调用了3次,第一次加@ 987654336@ 到 4,然后是 15,最后是 16,直到我们获得 7。换句话说:递归步骤必须调用add1递归 调用plus 的结果,其中x 保持不变,y 递减一个单位直到它达到零,并且此时我们到达了基本情况,递归展开并返回正确的结果。

【讨论】:

  • 为了增加愚蠢(双关语):add1 正在调用+,所以无论如何我们得到一个看起来像这样的扩展:(+ 1 (+ 1 (+ 1 4)))。所以是的,我们最终使用了+
  • 很可能他们打算将add1 用作此处的原语。 :)
  • 谢谢,我通过将 add1 移到 if 块中的递归调用之外,并将 x 和 sub1 y 传递到递归中来解决了这个问题。
猜你喜欢
  • 2018-12-29
  • 1970-01-01
  • 1970-01-01
  • 2013-06-19
  • 2019-02-10
  • 2016-02-24
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多