Recursion 在scheme中创建尾部递归幂函数
我想知道如何在scheme中实现尾部复活功率函数 我已经为scheme定义了递归:Recursion 在scheme中创建尾部递归幂函数,recursion,scheme,tail-recursion,Recursion,Scheme,Tail Recursion,我想知道如何在scheme中实现尾部复活功率函数 我已经为scheme定义了递归: (define power-is-fun (lambda (x y) (cond [(= y 0) 1] [(> y 0) (* (power-is-fun x (- y 1)) x)]))) 但是我不能很好地理解另一个应该是什么。答案是类似的,您只需将累积结果作为参数传递: (define power-is-fun (lam
(define power-is-fun
(lambda (x y)
(cond [(= y 0)
1]
[(> y 0)
(* (power-is-fun x (- y 1)) x)])))
但是我不能很好地理解另一个应该是什么。答案是类似的,您只需将累积结果作为参数传递:
(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
的调用是退出过程之前发生的最后一件事power is fun
顺便说一句,有一种更快的方法可以实现整数幂运算。与其将
x
一次又一次地乘以y
次(这使其成为O(y)),还有一种时间复杂度为O(logy)的方法:
(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
(正如我认识的许多Schemer所做的那样),这里有一个tail显式递归的版本(当然,您也可以使用命名的let
来编写它):
(顺便说一句,任何合适的方案实现都应该将两个版本宏扩展为完全相同的代码。此外,就像奥斯卡的解决方案一样,我使用累加器,只是在这里我称之为
r
(用于“结果”)。非常感谢。。。其他地方难以获得的信息:)
(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)))
(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))