Questions tagged «tail-recursion»

尾递归是一种递归策略,其中函数执行一些工作,然后调用自身。“尾部”指的是递归位于函数的最后。许多(尤其是功能强大的)编程语言编译器可以将这些类型的调用转换为迭代,这意味着可以使用支持的语言中的尾部递归,而不必担心堆栈溢出,无论调用数量如何。



19
如何在Scala中打破循环?
如何打破循环? var largest=0 for(i<-999 to 1 by -1) { for (j<-i to 1 by -1) { val product=i*j if (largest>product) // I want to break out here else if(product.toString.equals(product.toString.reverse)) largest=largest max product } } 如何将嵌套的循环转换为尾递归? 从FOSDEM 2009 上的Scala Talk http://www.slideshare.net/Odersky/fosdem-2009-1013261在第22页上: 中断并继续Scala没有它们。为什么?它们有点必要。更好地使用许多较小的函数发行如何与闭包进行交互。不需要它们! 有什么解释?

20
了解递归[关闭]
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意测验或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 7年前关闭。 我在学校了解递归时遇到了很大的麻烦。每当教授在谈论它时,我似乎都明白了,但是只要我自己尝试一下,它就会完全让我震惊。 我整夜试图解决河内塔楼,这完全让我震惊。我的教科书只有大约30页的递归,所以它不太有用。有谁知道可以帮助阐明这一主题的书籍或资源?

6
Python是否优化尾部递归?
我有以下代码,失败并出现以下错误: RuntimeError:超过最大递归深度 我试图重写此代码以允许尾递归优化(TCO)。我相信,如果发生了TCO,则该代码应该会成功。 def trisum(n, csum): if n == 0: return csum else: return trisum(n - 1, csum + n) print(trisum(1000, 0)) 我是否应该得出结论,Python不执行任何类型的TCO,还是只需要以不同的方式定义它?

5
哪些C ++编译器进行尾递归优化?
在我看来,在C和C ++中执行尾递归优化将非常有效,但是在调试时,我似乎从未看到指示这种优化的帧堆栈。这很好,因为堆栈告诉我递归的深度。但是,优化也会很好。 是否有任何C ++编译器都进行了此优化?为什么?为什么不? 如何告诉编译器执行此操作? 对于MSVC:/O2或/Ox 对于海湾合作委员会:-O2或-O3 在某些情况下,检查编译器是否已执行此操作呢? 对于MSVC,启用PDB输出以能够跟踪代码,然后检查代码 对于海湾合作委员会..? 我仍然会建议如何确定某个函数是否通过编译器进行了优化(即使我放心Konrad告诉我假设也是如此)。 总是可以通过进行无限递归检查编译器是否完全做到了这一点,并检查它是否导致无限循环或堆栈溢出(我用GCC这样做并发现-O2足够了),但是我想能够检查某个我知道会终止的功能。我希望有一个简单的方法来检查这个:) 经过一些测试,我发现析构函数破坏了进行此优化的可能性。有时更改某些变量和临时变量的范围以确保它们在返回语句开始之前超出范围是值得的。 如果在尾调用之后需要运行任何析构函数,则无法完成尾调用优化。

8
尾递归如何工作?
我几乎了解尾递归的工作原理以及它与普通递归之间的区别。我只是不明白为什么它不要求堆栈来记住它的返回地址。 // tail recursion int fac_times (int n, int acc) { if (n == 0) return acc; else return fac_times(n - 1, acc * n); } int factorial (int n) { return fac_times (n, 1); } // normal recursion int factorial (int n) { if (n == 0) return 1; …

6
.NET / C#为什么不优化尾调用递归?
我发现这个问题有关的语言优化尾递归。为什么C#尽可能不优化尾递归? 在具体情况下,为什么不将该方法优化为循环(如果需要的话,Visual Studio 2008 32位)? private static void Foo(int i) { if (i == 1000000) return; if (i % 100 == 0) Console.WriteLine(i); Foo(i+1); }

5
JVM是否阻止尾部调用优化?
我在以下问题上看到了这句话:构建Web服务时应使用哪种良好的功能语言? 除自递归功能外,Scala特别不​​支持尾部调用消除,这限制了您可以执行的组合类型(这是JVM的基本限制)。 这是真的?如果是这样,那么创建此基本限制的JVM是什么?

5
Ruby是否执行尾部调用优化?
函数式语言导致使用递归来解决许多问题,因此许多函数式语言执行尾部调用优化(TCO)。TCO导致从另一个函数(或其本身,在这种情况下也称为“尾递归消除”,它是TCO的子集)对该函数的调用,作为该函数的最后一步,不需要新的堆栈框架,这减少了开销和内存使用。 Ruby显然从功能语言(lambda,地图等功能)中“借用”了许多概念,这使我感到好奇:Ruby是否执行尾部调用优化?


4
Haskell是否具有尾递归优化?
我今天在Unix中发现了“ time”命令,以为我会用它来检查Haskell的尾递归函数与普通递归函数之间的运行时差异。 我编写了以下函数: --tail recursive fac :: (Integral a) => a -> a fac x = fac' x 1 where fac' 1 y = y fac' x y = fac' (x-1) (x*y) --normal recursive facSlow :: (Integral a) => a -> a facSlow 1 = 1 facSlow x = x …

7
foldl是尾递归的,那么foldr如何比foldl运行得更快?
我想测试foldl vs foldr。从我所看到的情况来看,由于尾部递归优化,您应该在可能的情况下使用foldl over foldr。 这很有道理。但是,运行此测试后,我感到困惑: 文件夹(使用时间命令时需要0.057s): a::a -> [a] -> [a] a x = ([x] ++ ) main = putStrLn(show ( sum (foldr a [] [0.. 100000]))) foldl(使用time命令时需要0.089s): b::[b] -> b -> [b] b xs = ( ++ xs). (\y->[y]) main = putStrLn(show ( sum (foldl b [] [0.. …

2
为什么递归调用会导致StackOverflow处于不同的堆栈深度?
我试图弄清楚C#编译器如何处理尾部调用。 (答案:不是。但是64位JIT将执行TCE(尾部调用消除)。有限制条件。) 因此,我使用递归调用编写了一个小型测试,该测试打印了在StackOverflowException终止进程之前被调用多少次。 class Program { static void Main(string[] args) { Rec(); } static int sz = 0; static Random r = new Random(); static void Rec() { sz++; //uncomment for faster, more imprecise runs //if (sz % 100 == 0) { //some code to keep this method from being …

3
JavaScript尾部调用中的函数是否已优化?
我一直试图Tail call optimization在JavaScript上下文中进行理解,并为编写了以下递归和尾递归方法factorial()。 递归: function factorial (n) { if (n < 2) { return 1; } else { return n * factorial(n-1); } } 尾递归: function factorial (n) { function fact(n, acc) { if (n < 2) { return acc; } else { return fact(n-1, n * acc); } } …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.