简体   繁体   English

素数递归StackOverflowException

[英]Prime number recursive StackOverflowException

I want to calculate prime numbers with a recursive function called primzahlenRekursiv , but I get a StackOverflowException in the function istPrimzahl , where I check if the current number is prime. 我想使用称为primzahlenRekursiv的递归函数来计算素数,但是我在函数istPrimzahl得到StackOverflowException ,在这里检查当前数是否为素数。

 static void Main(string[] args)
    {
        primzahlenRekursiv(2);
    }

    static void primzahlenRekursiv(int primzahl) 
    {
        if (istPrimzahl(primzahl, 2)) { Console.Writeline(primzahl); }
        primzahlenRekursiv(primzahl + 1);
    }

    static bool istPrimzahl(int primzahl, int zahl) 
    {
        if (primzahl % zahl != 0) { istPrimzahl(primzahl, zahl + 1); }
        if (primzahl == zahl) { return true; }
        return false;
    }

You have nothing in your recursive code that will ultimately end the recursion: 您的递归代码中没有任何东西最终将结束递归:

static void primzahlenRekursiv(int primzahl) 
{
    if (istPrimzahl(primzahl, 2)) { Console.Writeline(primzahl); }
    primzahlenRekursiv(primzahl + 1);
}

primzahlenRekursiv always calls itself without any condition to stop it. primzahlenRekursiv始终会在没有任何条件的情况下自行进行调用。 Since any method call needs space on the stack, your algorithm will run until your stack runs out. 由于任何方法调用都需要堆栈上的空间,因此算法将一直运行到堆栈用完为止。 Hence your exception. 因此,您的例外。

In fact there is no need to run your algorthim recursively: 实际上,不需要递归运行算法:

for (var kandidat = 2; ; kandidat++) {
    if (istPrimzahl(kandidat, 2)) { Console.Writeline(kandidat); }
}

This will run your code in an endless loop and not use up your stack that quickly . 这将使您的代码无休止地循环运行,而不会很快耗尽您的堆栈。 But be careful, eventually you will still run into a stack overflow exception if your candidate is getting high enough (you are still running recursion in istPrimzahl ), just later. 但是要小心,如果您的候选对象变得足够高(最终仍在 istPrimzahl运行递归),最终您仍然会遇到堆栈溢出异常。 Therefore you better constrain your number set (in this example to 10000): 因此,最好将数字集(在此示例中为10000)约束为:

for (var kandidat = 2; kandidat < 10000; kandidat++) {
    if (istPrimzahl(kandidat, 2)) { Console.Writeline(kandidat); }
}

Also, in your code your recursion is not running correctly because of another error: 另外,在代码中,由于另一个错误,递归未正确运行:

if (primzahl % zahl != 0) { istPrimzahl(primzahl, zahl + 1); }

...does not use the result of the recursive call. ...不使用递归调用的结果。 You are probably meaning to return the result of the recursive call at this spot. 您可能是想在此处返回递归调用的结果。

Another solution would of course be a tail call, but C# doesn't support that (althogh IL would). 另一个解决方案当然是尾部调用,但是C#不支持该方法(虽然IL会支持)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM