2011-10-12 7 views
7

私は学生の有限の数学を教えるhttp://finitehelp.comの数学ウェブサイトを持っています。 私は、電卓を組み込むのがいいと思っていたので、Javascriptで組み合わせと順列を作ったのです。ライブ計算機はhttp://finitehelp.com/finite-calculator.htmlです。私はJavascriptについては何も知らず、特に変数の過度の使用のために次のような記述を行うより効率的な方法があると推測します。誰かが私を助けてくれたら、私はとても感謝しています。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

私は、タスクを学生に割り当てることが最も効率的であると信じています。特別なメリットについて考えてみましょう!あなたが努力する必要はありませんが、生徒は新しいものも学び、必要に応じてコードを維持してアップグレードしてください。D。 – mingos

答えて

4

まあ、ここに行く!

まず、なぜあなたはこれを書く必要がありますか?

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

私は完全にそれをやめます。

また、あなたのMath.factorial少しクリーンアップすることができます。

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

をしかし、主な問題は、あなたの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; 

これは複雑すぎます。私はそれを機能させると、あなたのHTML内のがらくたのすべてを取り除くになる要素、それを結合して、それが少し簡単で動作するように作ると思います:

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

そして、ちょうどonclick=を取り除きますコード。

+0

は以下のabuotの再帰関数を説明しました。あなたの機能をベースとして使用しました。 – ymutlu

+0

これにより、アラートが2回ポップアップすることがわかりました。私はいくつかのリファクタリングを試みました。プログラムはしばらくの間働いていましたが、復帰して最初のプログラムと同じように改善できるかどうかを確認することは楽しいと思いました。私がほとんど諦めてくれたあなたの助けをありがとう。現在のバージョンはgithub https://gist.github.com/1861120にあります。どんなフィードバックやリファクタリングも評価されます。 – Justin

+0

私はそれに間違いを見つけることができません。良くやった! – Blender

0

私は再帰関数を好むだろう、テール再帰はフィボナッチのような関数のためのstackoverflowを引き起こすかもしれない。あなたは、効率を懸念している場合は

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

は、あなたはおそらく、反復機能ではなく、再帰的なものとして階乗を再実装したいと思います。再帰バージョンは、反復バージョンよりも多くのメモリとCPU時間を使用します。

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

また、独自の関数をMath名前空間に追加しないでください。それは良い習慣ではありません。

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