2011-10-12 9 views
7

Ho un sito web di matematica http://finitehelp.com che insegna agli studenti Finite Math. Ho pensato che sarebbe stato bello includere una calcolatrice, quindi ne ho creata una per le combinazioni e le permutazioni in Javascript. La calcolatrice live è http://finitehelp.com/finite-calculator.html. Non conosco quasi nulla di Javascript e mi permetto di indovinare che c'è un modo molto più efficace per scrivere quanto segue, in particolare a causa dell'uso eccessivo delle variabili. Se qualcuno potesse aiutarmi, sarei molto grato.Il modo più efficace per scrivere Calcolatrice di combinazioni e permutazioni in Javascript

<script type="text/javascript"> 
// calculate n! 
Math.factorial = function(n) 
{ 
    if(typeof n == 'string') n = Number(n); 
    if(typeof n != 'number' || isNaN(n)) 
    { 
     alert("Factorial requires a numeric argument."); 
     return null; 
    } 
    if (n < 2) return 1; 
    return (n * Math.factorial(n-1)); 
} 
Math.divide = function(a,b) 
{ 
    return a/b; 
} 
</script> 

<form class="form" name="combination" action=""> 
    <p>C(<input type="text" value="n" name="T1" size="1">,<input type="text" value="r" name="T2" size="1">) 
    <input type="button" value="Calculate" 
    onclick="var n = T1.value; var r = T2.value; var n_minus_r = parseFloat(n) - parseFloat(r); var numerator = Math.factorial(T1.value); var n_minus_r_fact = Math.factorial(n_minus_r); var r_fact = Math.factorial(r); var denominator = n_minus_r_fact * r_fact; T3.value = Math.divide(numerator,denominator); return true;"> 
    = <input type="text" name="T3" size="12" readonly></p> 
</form> 
+0

Credo che sarà il modo più efficiente di assegnare il compito a uno studente. Pensa ai benefici extra! A prescindere dal fatto che non richiede alcuno sforzo da parte tua, lo studente imparerà anche nuove cose, e, auspicabilmente, manterrà e aggiornerà il codice in caso di necessità: D. – mingos

risposta

4

Bene, eccoci!

Prima di tutto, perché avresti mai bisogno di scrivere questo?

Math.divide = function(a,b) 
{ 
    return a/b; 
} 

Vorrei eliminarlo completamente.

È anche possibile ripulire il Math.factorial un po ':

Math.factorial = function(n) 
{ 
    n = Number(n); 

    if (isNAN(n)) { 
     alert("Factorial requires a numeric argument."); 
     return null; 
    } else if (n < 2) { 
     return 1; 
    } else { 
     return (n * Math.factorial(n - 1)); 
    } 
} 

Ma il problema principale è il codice onclick():

onclick="var n = T1.value; var r = T2.value; var n_minus_r = parseFloat(n) - parseFloat(r); var numerator = Math.factorial(T1.value); var n_minus_r_fact = Math.factorial(n_minus_r); var r_fact = Math.factorial(r); var denominator = n_minus_r_fact * r_fact; T3.value = Math.divide(numerator,denominator); return true; 

Questo è modo troppo complicato. Mi rendono una funzione e associarlo all'elemento, che sarebbe sbarazzarsi di tutte le stronzate nel tuo codice HTML e renderlo un po 'più facile lavorare con:

window.onload = function() 
{ 
    document.getElementById('calculate').onclick = function() { 
     var n = T1.value, 
      r = T2.value; 

     T3.value = Math.factorial(n)/(Math.factorial(r) * Math.factorial(n - r)); 
    } 
} 

E proprio a sbarazzarsi del onclick= codice.

+0

appena menzionato funzione ricorsiva di seguito. Ha usato la tua funzione come base. – ymutlu

+0

Ho notato che questo fa apparire l'avviso due volte. Ho provato a fare un po 'di refactoring. Il programma ha funzionato per un po 'ora, ma ho pensato che sarebbe stato divertente ritornarci e vedere come posso migliorarlo dato che era il mio primo programma. Grazie mille per il tuo aiuto che mi ero quasi arreso. La versione corrente è su github https://gist.github.com/1861120. Qualsiasi feedback o refactoring sarebbe apprezzato. – Justin

+0

Non riesco a trovare niente di sbagliato in questo. Bel lavoro! – Blender

0

Preferirei la funzione ricorsiva, coda ricorsiva può causare stackoverflow per funzioni come Fibonacci.

Math._factorial = function(n){ 
    return Math._fact(n,1); 
} 

Math._fact= function(n,res){ 
    n = Number(n); 
    if (n == null) { 
    alert("Factorial requires a numeric argument."); 
    return null; 
    } else if (n < 2){ 
    return res; 
    } else { 
    return Math._fact(n-1, res*n); 
    } 
} 
4

Se siete preoccupati per l'efficienza, si sarebbe probabilmente vuole re-implementare il fattoriale come una funzione iterativa piuttosto che uno ricorsivo. La versione ricorsiva utilizzerà molta più memoria e tempo CPU rispetto alla versione iterativa.

function factorial(n) { 
    var x=1; 
    var f=1; 
    while (x<=n) { 
    f*=x; x++; 
    } 
    return f; 
} 

Non è inoltre necessario aggiungere le proprie funzioni allo spazio dei nomi Math. Non è una buona abitudine entrare.

1
Math.factorial= function(n){ 
    var i= n; 
    while(--i) n*= i; 
    return n; 
} 

Math.combinations= function(n, r, repeats){ 
    if(n< r) return 0; 
    if(n=== r) return 1; 
    if(repeats){ 
     return Math.factorial(n+r-1)/((Math.factorial(r)*Math.factorial(n-1))); 
    } 
    return Math.factorial(n)/((Math.factorial(r)*Math.factorial(n-r))); 
} 


var a= [ 
    'aqua', 'black', 'blue', 'fuchsia', 'gray', 'green', 'lime', 'maroon', 
    'navy', 'olive', 'orange', 'purple', 'red', 'silver', 'teal', 'white', 
    'yellow' 
] 
//how many 3 color combinations are there? 
//[red,green,blue] is different than [green,red,blue] 
// Math.combinations(a.length,3,true) >>969 
// how many unique combinations (ignoring order) are there? 
// Math.combinations(a.length,3)>>680 
Problemi correlati