Guardando il codice, non c'è da meravigliarsi che si esaurirà la memoria abbastanza velocemente. Il tuo metodo divideFactorials
chiama il metodo fattoriale e usa come argomento la differenza "numeratore-denominatore". Probabilmente questa differenza sarà molto grande in base al tuo codice e sarai bloccato in un ciclo molto lungo nel tuo metodo fattoriale.
Se è davvero solo di trovare NCK (che presumo perché il tuo commento nel codice), basta usare:
public static long GetnCk(long n, long k)
{
long bufferNum = 1;
long bufferDenom = 1;
for(long i = n; i > Math.Abs(n-k); i--)
{
bufferNum *= i;
}
for(long i = k; i => 1; i--)
{
bufferDenom *= i;
}
return (long)(bufferNom/bufferDenom);
}
Naturalmente con questo metodo verrà eseguito fuori portata molto veloce, perché un long in realtà non supporta numeri molto lunghi, quindi n e k devono essere minori di 20.
Supponendo che si lavori effettivamente con numeri molto grandi, si possono usare doppi invece di lunghi, poiché i poteri diventano sempre più significativi.
Edit: Se si utilizza un gran numero si potrebbe anche usare la formula di Stirling:
Come n diventa grande ln -> n * ln (n) - n (n!).
Mettendo questo in codice:
public static double GetnCk(long n, long k)
{
double buffern = n*Math.Log(n) - n;
double bufferk = k*Math.Log(k) - k;
double bufferkn = Math.Abs(n-k)*Math.Log(Math.Abs(n-k)) - Math.Abs(n-k);
return Math.Exp(buffern)/(Math.Exp(bufferk)*Math.Exp(bufferkn));
}
propongo solo questa risposta, come hai detto linguaggio indipendente, il codice C# è solo utilizzato per dimostrarlo. Dal momento che è necessario utilizzare numeri grandi per n e k perché ciò funzioni, propongo questo come un modo generale per trovare il coefficiente binomiale per le combinazioni grandi.
Per i casi in cui n e k sono entrambi inferiori a circa 200-300, è necessario utilizzare la risposta che Victor Mukherjee ha proposto, in quanto è esatta.
Edit2: Modificato il mio primo codice.
Questi numeri sono chiamati "coefficienti binomiali" e come un oggetto molto comune, sono apparsi prima nella SO: http://stackoverflow.com/q/4256188/422353 – madth3
Che tipo di combinazione esattamente stai cercando di ottenere? È semplicemente nCk, o è qualcos'altro? Sto solo chiedendo perché il tuo commento in alto dice "nCk" ma il tuo codice non lo calcola direttamente. – phil13131
Sì, aggiungi questa riga a factorial(): 'if (n> 20) getta nuovo OverflowException();' –