2016-12-09 18 views
0

primzahlenRekursivと呼ばれる再帰関数で素数を計算したいが、私はistPrimzahlStackOverflowExceptionを得て、現在の数が素数であるかどうかをチェックする。素数再帰的な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; 
    } 
+4

最初に注意する:あなたは結果を使用して 'istPrimzahl'とされていない呼び出しているすべての時間は、それはバグです... –

+1

あなたは、これは発生しません宇宙のすべての素数を見つけたいです。あなたの再帰の終わりはどこですか? – mybirthname

+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#がその(ILが希望althogh)をサポートしていません。

+0

ええ、私は知っています。しかし、私たちはC#であり、この文脈の中で、私の主張はまだそこに尾行がないので、真実を保持しています。 –

+0

を除く「任意のメソッド呼び出しは、スタック上のスペースを必要とするので、」 – Sefe

+0

C#の/ NETは、尾がPawełŁ[email protected] –