运行时异常,递归太深 [英] Runtime exception, recursion too deep

查看:208
本文介绍了运行时异常,递归太深的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我转换了伪代码 here 进入C#,并递归重复10,000次。但是在 9217 次之后,我收到一个C#运行时错误, StackOverflow Exception 如何防止这种情况?



编辑如果它有助于任何人,这里是代码:



pre> private double CalculatePi(int maxRecursion)
{
return 2 * CalculatePi(maxRecursion,1);
}

private double CalculatePi(int maxRecursion,int i)
{
if(i> = maxRecursion)
return 1;
return 1 + i /(2.0 * i + 1)* CalculatePi(maxRecursion,i + 1);
}

double pi = CalculatePi(10000); // 10,000递归

EDIT2 所以大家似乎都同意我需要转换为迭代...任何人可以给一些代码?我似乎无法编写任何可以工作的迭代代码...



编辑感谢Paul Rieck为我做了这个答案,它的工作原理:

  private static double CalculatePi(int maxRecursion)
{
double result = 1;
for(int i = maxRecursion; i> = 1; i--)
{
result = 1 + i /(2.0 * i + 1)* result;
}
返回结果* 2;
}


解决方案

c#编译这个罚款。但是,在运行时,您可能会遇到一个StackOverflow异常(在我的机器上,10,000个工作正常,但后来死亡)。



这不是一个无限递归异常 - 堆栈溢出正是它所说的;调用方法意味着将信息放在堆栈上,并在调用返回时将其删除。您有10,000个呼叫,没有任何返回,所以堆栈已满,异常被抛出。



您可以在这种特殊情况下很容易地解决这个问题,通过删除递归和反复运行。在一般情况下,有一些方法可以通过迭代,尾递归优化和继续传递去除递归。



这是一个快速的直接翻译成迭代样式: p>

  private static double CalculatePi(int maxRecursion)
{
double result = 1;
for(int i = maxRecursion -1; i> = 1; i--)
{
result = 1 + i /(2.0 * i + 1)* result;
}
返回结果* 2;
}


I converted the pseudo-code here into C#, and have it recursively repeat 10,000 times. But I get a C# runtime error, StackOverflow Exception after 9217 times. How can I prevent this?

EDIT If it helps anybody, here's the code:

    private double CalculatePi(int maxRecursion)
    {
        return 2 * CalculatePi(maxRecursion, 1);
    }

    private double CalculatePi(int maxRecursion, int i)
    {
        if (i >= maxRecursion)
            return 1;
        return 1 + i / (2.0 * i + 1) * CalculatePi(maxRecursion, i + 1);
    }

    double pi = CalculatePi(10000); // 10,000 recursions

EDIT2 So everybody seems to agree that i need to convert this to iterative... can anybody give some code? I can't seem to write any iterative code that works...

EDIT Thanks to Paul Rieck for this answer, which I tested, and it works:

    private static double CalculatePi(int maxRecursion)
    {
        double result = 1;
        for (int i = maxRecursion; i >= 1; i-- )
        {
            result = 1 + i / (2.0 * i + 1) * result;
        }
        return result * 2;
    }

解决方案

The "c# compiler" will compile this fine. At runtime, however, you may end up with a StackOverflow exception (on my machine, 10,000 works fine, but dies later).

This is not an "infinite recursion exception" - stack overflow is exactly what it says; calling a method means putting information on the stack and removing it when the call returns. You have 10,000 calls and none have returned, so the stack is full and the exception is thrown.

You can fix this fairly easily in this particular case by removing the recursion and running iteratively. In the general case, there are ways to remove recursion via iteration, tail-recursion optimization, and continuation passing.

Here's a quick direct translation to an iterative style:

private static double CalculatePi(int maxRecursion)
        {
            double result = 1;
            for (int i = maxRecursion -1; i >= 1; i-- )
            {
                result = 1 + i / (2.0 * i + 1) * result;
            }
            return result * 2;
        }

这篇关于运行时异常,递归太深的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆