运行时异常,递归太深。

29 浏览
0 Comments

运行时异常,递归太深。

我将这里的伪代码转换成了C#,并且递归地重复了10000次。但是我在执行第9217次后遇到了C#运行时错误StackOverflow Exception。我该如何防止这种情况发生?\n编辑 如果对任何人有所帮助,这是代码:\n

    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); // 递归10000次

\n编辑2 所有人似乎都同意我需要将其转换为迭代方法...有人能给出一些代码吗?我似乎无法编写任何有效的迭代代码...\n编辑 感谢Paul Rieck的答案,我已经测试过,它有效:\n

    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;
    }

0
0 Comments

(Runtime exception, recursion too deep)这个问题的出现主要是由于使用了递归导致的。在这个案例中,不应该使用递归,因为这样做会导致调用堆栈溢出。可以很容易地将其转换为非递归方式。

递归是一种在函数或方法内部调用自身的编程技术。它通常用于解决可以被分解为相同问题的子问题的情况。然而,当递归的深度太深时,就会出现调用堆栈溢出的问题。

调用堆栈是用来存储函数调用信息的一种数据结构。每当一个函数被调用时,相关的信息(如参数、返回地址等)都会被压入调用堆栈中。当函数执行完毕后,这些信息会被弹出,程序继续执行下一个函数。但是,如果递归的深度太深,即函数调用自身的次数过多,调用堆栈的空间可能会超出其限制,导致调用堆栈溢出。

要解决这个问题,最好的方法是将递归函数转换为非递归方式。非递归方式通常使用循环结构来代替递归调用。这样可以避免调用堆栈溢出的问题,提高程序的性能和稳定性。

以下是一个示例代码,演示了如何将递归函数转换为非递归方式:

public int nonRecursiveMethod(int n) {

int result = 0;

while (n > 0) {

result += n;

n--;

}

return result;

}

在这个示例中,我们将原来的递归函数转换为了一个循环结构。通过使用一个循环变量n,不断减小n并累加结果result,最终得到了相同的结果。

,要避免(Runtime exception, recursion too deep)这个问题,我们应该避免在不必要的情况下使用递归,并尽可能地将递归函数转换为非递归方式。这样可以避免调用堆栈溢出的问题,提高程序的性能和稳定性。

0
0 Comments

在这个问题中,出现了(Runtime exception, recursion too deep)错误。这个错误的原因是递归调用的层数过深导致栈溢出异常。递归调用会将信息存储在栈中,并在调用返回时将其移除。当递归调用的次数过多时,栈的容量会被填满,从而引发异常。

解决这个问题的方法有多种。在这个特定的例子中,可以通过将递归改为迭代来轻松解决。在一般情况下,可以通过迭代、尾递归优化和继续传递等方式来消除递归。

下面是将递归改写为迭代的示例代码:

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;
}

需要将maxRecursion减1以获得与递归版本完全相同的结果。请参考我的回答中的代码。

通过将递归改为迭代,可以避免递归调用层数过深导致的栈溢出异常。这种改写的方法可以应用于其他类似的递归问题,以提高程序的性能和稳定性。

0
0 Comments

在这段对话中,一个人询问了如何将递归代码转换为迭代代码,并且表示自己无法编写能够正常工作的迭代代码。然后,另一个人指出了将递归代码转换为迭代代码的一种简单方法,并给出了一个示例代码。这段代码计算了一个数学表达式的乘积。接下来,这个人还提到了其他解决这个问题的方法。其中一种方法是使用聚合器,另一种方法是通过构建堆上的堆栈结构来解决栈溢出的问题。此外,他还提到了使用Continuation Passing Style和编写虚拟机来解决递归过深的问题,但是他也指出解释这些技术需要很长的篇幅,并提供了一个链接以供进一步阅读。

因此,问题的出现原因是递归调用过深,导致栈溢出。解决方法包括将递归代码转换为迭代代码、使用聚合器、构建堆上的堆栈结构、使用Continuation Passing Style等。具体的方法和代码示例在上面的对话中已经给出。如果需要进一步了解这些方法的详细信息,还可以阅读提供的链接。

0