问题标签 [tail-recursion]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
algorithm - 这个实现是尾递归的吗
我在一本算法书中读到 Ackermann 函数不能进行尾递归(他们说的是“它不能转换为迭代”)。我对此很困惑,所以我尝试了这个:
(这是 OCaml / F# 代码)。
我的问题是,我不确定这实际上是尾递归。你能确认是吗?如果不是,为什么?最后,当人们说阿克曼函数不是原始递归时,这是什么意思?
谢谢!
scala - 如何使用 TailCall?
如果我理解正确, scala.util.control.TailCalls 可用于通过使用蹦床来避免非尾递归函数的堆栈溢出。API 中给出的示例很简单:
但是,更有趣的情况是,如果您想在 recurve 调用之后进行一些操作。我得到了一个“天真的”阶乘实现以某种方式运行
但这看起来很可怕,我怀疑这是预期用途。所以我的问题是如何使用 TailCalls 正确编写阶乘或斐波那契函数(是的,我知道如何使用累加器使它们尾递归)?还是 TailCalls 不适合这种问题?
java - 我在此代码上收到 StackOverFlowException 异常,因为我的 JVM 不支持尾调用优化,对吗?
我得到了StackOverflowException
这个 Java 方法:
我正在玩尾调用递归,所以我想这就是当 JVM 不短路堆栈时会发生的情况,对吧?
recursion - Mathematica 中的尾调用优化?
在制定另一个 SO question 的答案时,我遇到了一些关于 Mathematica 中尾递归的奇怪行为。
Mathematica 文档提示可能会执行尾调用优化。但是我自己的实验给出了相互矛盾的结果。对比一下,例如下面两个表达式。第一个使 7.0.1 内核崩溃,可能是由于堆栈耗尽:
第二个运行完成,似乎利用尾调用优化来返回有意义的结果:
两个表达式都定义了一个尾递归函数f
。在第一个函数的情况下,Mathematica 显然认为复合语句的存在足以阻止任何尾调用优化的机会。另请注意,第一个表达式受控于$RecursionLimit
,第二个受控于$IterationLimit
-- 这表明 Mathematica 对这两个表达式的处理方式不同。(注意:上面引用的 SO 答案有一个不那么做作的函数,它成功地利用了尾调用优化)。
所以,问题是:有谁知道 Mathematica 在什么情况下执行递归函数的尾调用优化?最好参考 Mathematica 文档或其他WRI材料中的明确声明。也欢迎投机。
c++ - g ++中的尾递归问题
我在 C++ 中搞乱尾递归函数,并且在使用 g++ 编译器时遇到了一些问题。
当numbers[]
大小超过几百个整数时,以下代码会导致堆栈溢出。检查由 g++ 生成的汇编代码,发现 twoSum_Helper 正在call
对自身执行递归指令。
问题是以下哪项导致了这种情况?
- 以下是我忽略的一个错误,它阻止了尾递归。
- 我使用 g++ 的错误。
- 在 g++ 编译器中检测尾递归函数的缺陷。
我正在g++ -O3 -Wall -fno-stack-protector test.c
使用 g++ 4.5.0 通过 MinGW 在 Windows Vista x64 上进行编译。
scala - Scala tailrec注释错误
我有一个名为的 Java 抽象类ImmutableEntity
和几个包含名为@DBTable
. 我正在尝试使用尾递归 Scala 方法在类层次结构中搜索注释:
当我编译这段代码时,我收到错误消息:“无法优化 @tailrec 注释方法:它是用不同类型的参数递归调用的”。我的内在方法有什么问题?
谢谢。
recursion - "and" 和尾递归
我可以在and
语句中使用递归调用来构建迭代过程吗?
例如,目的,我们有foo
不做任何事情的功能。它将创建什么样的过程(迭代或递归)?
clojure - 尾递归函数不应该也更快吗?
我有以下 Clojure 代码来计算具有特定“可分解”属性的数字。(代码的确切作用是次要的)。
现在,我进入 TCO 并意识到 Clojure 只有在使用recur
关键字明确告知时才能提供尾递归。所以我重写了代码来做到这一点(用 recur 替换 factor-9 是唯一的区别):
据我所知,TCO 有双重好处。第一个是它没有像非尾递归调用那样大量使用堆栈,因此不会在更大的递归上破坏它。第二个,我认为因此它更快,因为它可以转换为循环。
现在,我做了一个非常粗略的基准测试,但没有看到这两种实现之间有任何区别。我的第二个假设是错误的,还是这与在 JVM(没有自动 TCO)上运行并recur
使用技巧来实现它有关?
谢谢你。
javascript - 关于“尾调用优化”文章的问题
我有一个关于这篇文章的问题。
这段代码之间
和这段代码
1)我对这有多大帮助感到困惑。第二个片段是否只是有一个尾调用,它会产生更少的开销,因为它会在再次调用自己之前计算它需要什么,或者我还缺少什么?
据我了解,尾调用仍未消除,只是进行了优化。
2)为什么需要odds
和odds1
无论如何?我也不清楚。
scala - 为什么除非方法是最终的,否则 Scala 编译器不会应用尾调用优化?
为什么除非方法是最终的,否则 Scala 编译器不会应用尾调用优化?
例如,这个:
结果是
错误:无法优化 @tailrec 注释方法:它既不是私有的也不是最终的,因此可以被覆盖
如果编译器在这种情况下应用TCO ,究竟会出现什么问题?