如何评估堆栈溢出之前递归调用最多递归、最多、堆栈

2023-09-11 23:19:35 作者:冬卉

让我们递归函数,比如阶乘。让我们还假设,我们有一叠1 MB的大小。使用笔和纸,我怎么能估计的递归调用堆栈溢出之前的号码功能?我不感兴趣的任何特定的语言,而是以一种抽象的方式。

有看起来类似上做题,但其中大部分都涉及特定的语言,或扩展堆栈大小,或通过运行特定的功能,或preventing溢出估测。我想找个估计它的数学方法。

我发现了类似的问题,在算法的挑战,但未能拿出任何合理的解决方案。

任何建议高度AP preciated。

修改

通向Golang的捷径

在应对提供的录像,如果真的不能带出式的语言,让我们假设它是C#。此外,由于我们传递简单的int或长的功能它不是通过参考,但作为副本通过。另外,假设一个幼稚实现,而不散列,无需多线程,即尽可能地类似于函数的数学重新presentation一个实施

 私有静态长因子(N久)
    {
        如果(正℃,)
        {
            抛出新的ArgumentException(不支持负数);
        }

        开关(N)
        {
            情况下0:
                返回1;
            情况1:
                返回1;
            默认:
                返回N *阶乘(N  -  1);
        }
    }
 

解决方案

这在很大程度上取决于该功能的实现。多少内存功能的使用,再次调用本身之前。当递归100倍,你也将有100的功能范围的内存,包括函数的参数和变量。它还保留了堆栈来存储返回值的100个名额。

我不认为语言可以很容易地取出等式,因为你需要确切地知道如何使用堆栈。对于实例对象按引用传递?或者,将对象复制为堆栈上一个新的实例?

Lets take a recursive function, for example factorial. Lets also assume that we have a stack of 1 MB size. Using a pen and paper, how can I estimate the number of recursive calls to the function before the stack overflows? I'm not interested in any particular language but rather in an abstract approach.

There are questions on SO that look similar but most of them are concerned with a specific language, or extending stack size, or estimating it by running specific function, or preventing overflow. I would like to find a mathematical way to estimate it.

I found similar question in an algorithmic challenge but couldn't come up with any reasonable solution.

Any suggestion highly appreciated.

EDIT

In response to provided replays if the language truly cannot be taken out of the equation let's assume it's C#. Also, since we are passing simple int or long to the function it's not passed by reference but as a copy. Also, assume a naive implementation, without hashing, without multi-threading, an implementation that as much as possible resembles a mathematical representation of the function:

    private static long Factorial(long n)
    {
        if (n < 0)
        {
            throw new ArgumentException("Negative numbers not supported");
        }

        switch (n)
        {
            case 0:
                return 1;
            case 1:
                return 1;
            default:
                return n * Factorial(n - 1);
        }
    }

解决方案

It highly depends on the implementation of the function. How much memory does the function use, before calling itself again. When it recurses 100 times, you will also have 100 function scopes in memory, including the function arguments and variables. It also reserves 100 places on the stack to store the return values.

I don't think the language can easily be taken out of the equation, because you need to know exactly how the stack is used. For examples are objects passed by reference? Or are the objects copy as a new instance on the stack?