素数递归StackOverflowException

时间:2016-12-09 13:50:49

标签: c# recursion

我想用一个名为primzahlenRekursiv的递归函数来计算素数,但我在函数StackOverflowException中得到一个istPrimzahl,在那里我检查当前的数字是否为素数。

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

1 个答案:

答案 0 :(得分:1)

您的递归代码中没有任何内容可以最终结束递归:

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

primzahlenRekursiv总是在没有任何条件的情况下自行调用它来阻止它。由于任何方法调用都需要堆栈上的空间,因此算法将一直运行直到堆栈用完为止。因此你的例外。

事实上,没有必要递归地运行你的algorthim:

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

这将在无限循环中运行您的代码,而不会快速耗尽您的堆栈 。但是要小心,如果你的候选人变得足够高(你仍然在istPrimzahl中运行递归),你最终会仍然遇到堆栈溢出异常。因此,您可以更好地约束您的数字集(在此示例中为10000):

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

此外,在您的代码中,由于另一个错误,您的递归无法正常运行:

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

...不使用递归调用的结果。你可能想在这个地方返回递归调用的结果。

另一种解决方案当然是尾调用,但C#不支持(althogh IL会)。