我想知道你如何在方案中实现尾部回复功率函数?
我已为计划定义了递归:
(define power-is-fun
(lambda (x y)
(cond [(= y 0)
1]
[(> y 0)
(* (power-is-fun x (- y 1)) x)])))
但我无法弄清楚另一个应该是怎样的。
答案 0 :(得分:5)
答案类似,您只需将累积结果作为参数传递:
(define power-is-fun
(lambda (x y acc)
(cond [(= y 0)
acc]
[(> y 0)
(power-is-fun x (- y 1) (* x acc))])))
这样调用它,注意acc
的初始值是1
(你可以为此构建一个辅助函数,所以你不必记住传递1
}每次):
(power-is-fun 2 3 1)
> 8
将递归过程转换为尾递归的一些通用指针:
power-is-fun
之后执行了乘法,而在尾递归版本中,对power-is-fun
的调用是在退出之前发生的最后一件事程序答案 1 :(得分:2)
顺便说一句,有一种更快的方法来实现整数取幂。而不是一次又一次地x
乘以y
次(这使得它成为O(y)),有一种方法是时间复杂度为O(log y):
(define (integer-expt x y)
(do ((x x (* x x))
(y y (quotient y 2))
(r 1 (if (odd? y) (* r x) r)))
((zero? y) r)))
如果您不喜欢do
(我知道的Schemers数量很多),这里有一个明确尾部recurses的版本(当然,您也可以使用名为let
编写它:
(define (integer-expt x y)
(define (inner x y r)
(if (zero? y) r
(inner (* x x)
(quotient y 2)
(if (odd? y) (* r x) r))))
(inner x y 1))
(顺便说一句,任何体面的Scheme实现都应该将两个版本宏扩展到完全相同的代码。另外,就像Óscar的解决方案一样,我使用累加器,只在这里我称之为r
(对于“结果” “)。)
答案 2 :(得分:1)
Óscar的建议清单非常好。
如果您想更深入地处理迭代(又称线性递归)和树递归过程,那么请不要错过SICP中的优秀处理:
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_sec_1.2