簡體   English   中英

素數遞歸StackOverflowException

[英]Prime number recursive StackOverflowException

我想使用稱為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;
    }

您的遞歸代碼中沒有任何東西最終將結束遞歸:

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

primzahlenRekursiv始終會在沒有任何條件的情況下自行進行調用。 由於任何方法調用都需要堆棧上的空間,因此算法將一直運行到堆棧用完為止。 因此,您的例外。

實際上,不需要遞歸運行算法:

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#不支持該方法(雖然IL會支持)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM