2011-10-12 11 views
7

Tengo un sitio web de matemáticas http://finitehelp.com que enseña a los estudiantes matemáticas finitas. Pensé que sería genial incluir una calculadora, así que hice una para combinaciones y permutaciones en Javascript. La calculadora en vivo está en http://finitehelp.com/finite-calculator.html. No sé casi nada sobre Javascript y me atrevería a adivinar que hay una forma mucho más eficiente de escribir lo siguiente, particularmente debido al uso excesivo de variables. Si alguien pudiera ayudarme, estaría muy agradecido.La forma más eficiente de escribir la calculadora de combinación y permutación en 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

Creo que será más eficiente asignar la tarea a un alumno. ¡Piensa en los beneficios adicionales! Además de que no requiere ningún esfuerzo de su parte, el alumno también aprenderá cosas nuevas, y con suerte mantendrá y actualizará el código si fuera necesario: D. – mingos

Respuesta

4

Bueno, aquí vamos!

Antes que nada, ¿por qué necesitarías escribir esto?

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

Me gustaría eliminarlo por completo.

También puede limpiar su Math.factorial un poco:

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

Pero el problema principal es el código de 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; 

Ésta es manera demasiado complicado. Me gustaría hacer que una función y se unen al elemento, lo que deshacerse de toda la basura en su HTML y que sea un poco más fácil trabajar 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)); 
    } 
} 

y deshacerse de la onclick= solo código.

+0

acaba de mencionar la función recursiva de abuot a continuación. Usó su función como base. – ymutlu

+0

Noté que esto hace que la alerta aparezca dos veces. Intenté hacer algo de refactorización. El programa ha estado funcionando por un tiempo, pero pensé que sería divertido regresar y ver cómo puedo mejorarlo, ya que era mi primer programa. Muchas gracias por su ayuda, casi me había dado por vencido. La versión actual está en github https://gist.github.com/1861120. Cualquier comentario o refactorización sería apreciado. – Justin

+0

No puedo encontrar nada malo con eso. ¡Buen trabajo! – Blender

0

Preferiría la función recursiva, la cola recursiva puede causar un flujo de acumulación para funciones como 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

Si usted está preocupado por la eficiencia, usted probablemente querrá volver a implementar el factorial como una función iterativa en lugar de una recursiva. La versión recursiva usará mucha más memoria y tiempo de CPU que la versión iterativa.

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

Tampoco debe agregar sus propias funciones al espacio de nombre matemático. No es un buen hábito entrar.

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 
Cuestiones relacionadas