是否有可能产生 40,000+ Lisp 中递归斐波那契元素?
我正在尝试用 Lisp 解决 Project Euler 问题 2。这个递归解决方案在执行时会破坏堆栈,但我认为 Lisp(使用 clisp)会识别尾递归。这正在进入顶层。
(defun e2-problem (&optional (f1 1) (f2 1) (sum 0))
"Sum fibonacci sequence, even terms up to 4 million"
(if (> f2 4000000) sum)
(e2-problem f2 (+ f1 f2) (if (evenp f2)
(+ sum f2)
sum))
我的实现是否没有正确安排优化?我想,如果我不能依赖惯用的递归,这会严重阻碍我的 Lisp 教育。
I'm trying to solve Project Euler question 2 with Lisp. This recursive solution blows the stack on execution, but I thought Lisp (using clisp) would recognize the tail recursion. This is being entered into the top-level.
(defun e2-problem (&optional (f1 1) (f2 1) (sum 0))
"Sum fibonacci sequence, even terms up to 4 million"
(if (> f2 4000000) sum)
(e2-problem f2 (+ f1 f2) (if (evenp f2)
(+ sum f2)
sum))
Is my implementation not correctly arranged for optimization? I imagine this would hinder my Lisp education quite a bit if I could not rely on idiomatic recursion.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
递归(甚至迭代)是不必要的!
每三个斐波那契数都是偶数:
并且由于每个偶数斐波那契数 (粗体)是前面两个奇数斐波那契数的和,Fn 之前偶数个斐波那契数的和恰好是以下的一半所有斐波那契数列的总和,直至 Fn(如果 Fn当然是偶数)。
现在,前 n 个斐波那契数之和为 Fn+2 − 1。这很容易通过归纳法来检查:前 n+ 1 斐波那契数之和为 F1+ ;F2 + ...+ Fn + ;Fn+1,等于 Fn+2 − 1 + 根据假设,Fn+1,根据定义等于 Fn+3 − 1斐波那契数列。
因此,如果您可以找到最大的 N 使得 F3N ≤ 4,000,000,那么要求的总和将是 ( F3N+2 − 1) / 2。
(我将把剩下的细节留给你,但从这里开始应该很简单。)
Recursion (or even iteration) is not necessary!
Every third Fibonacci number is even:
and since each even Fibonacci number (in bold) is the sum of the two preceding odd Fibonacci numbers, the sum of the even Fibonacci numbers up to Fn is exactly half of the sum of all the Fibonacci numbers up to Fn (if Fn is even, of course).
Now, the sum of the first n Fibonacci numbers is Fn+2 − 1. This is easy to check by induction: the sum of the first n + 1 Fibonacci numbers is F1 + F2 + ... + Fn + Fn+1, which equals Fn+2 − 1 + Fn+1 by hypothesis, which equals Fn+3 − 1 by the definition of the Fibonacci numbers.
So if you can find the largest N such that F3N ≤ 4,000,000, then the sum that’s asked for will be (F3N+2 − 1) / 2.
(I'll leave the remaining details to you but it should be straightforward from here.)
1) 代码中正确的语法错误:
2) 使用SBCL< /a>。 CLISP 不足以检测尾递归。
3) 使用最高的可用优化级别:
1) Correct syntax error in code:
2) use SBCL. CLISP is not kind enough to detect tail recursion.
3) use highest available optimization level:
对于实现尾调用消除的环境,Scheme 中是强制的< /a>,但在大多数其他 Lisp 方言中则不然,例如 Common Lisp。
For an environment to implement tail call elimination is mandatory in Scheme, but not in most other Lisp dialects, such as Common Lisp.
您的代码实现了无限循环。它不会终止。
使用循环:
Your code implements an endless loop. It does not terminate.
Using LOOP: