【发布时间】:2018-01-21 15:24:33
【问题描述】:
只是为了好玩(Project Euler #65)我想实现公式
n_k = a_k*n_k-1 + n_k-2
以一种有效的方式。 a_k 是1 或(* 2 (/ k 3)),取决于k。
我从递归解决方案开始:
(defun numerator-of-convergence-for-e-rec (k)
"Returns the Nth numerator of convergence for Euler's number e."
(cond ((or (minusp k)) (zerop k) 0)
((= 1 k) 2)
((= 2 k) 3)
((zerop (mod k 3)) (+ (* 2 (/ k 3) (numerator-of-convergence-for-e-rec (1- k)))
(numerator-of-convergence-for-e-rec (- k 2))))
(t (+ (numerator-of-convergence-for-e-rec (1- k))
(numerator-of-convergence-for-e-rec (- k 2))))))
这适用于小型k,但对于k = 100 显然会很慢。
我不知道如何将此函数转换为可以进行尾调用优化的版本。我已经看到一个使用两个累加变量的模式 fibonacci numbers 但未能将此模式转换为我的函数。
是否有如何将复杂递归转换为 tco 版本的一般指南,或者我应该直接实施迭代解决方案。
【问题讨论】:
-
在这种情况下,简单地记忆函数可能是最简单的解决方案。
-
我在想它,但从未在现实生活中使用过这种技术。有这方面的好图书馆吗?
-
Fare-memoization 应该可以工作。或者只是手动将结果存储到一个向量中,并在后续调用中使用相同的
K从那里查找它们。
标签: recursion common-lisp tail-call-optimization