2011-10-12 61 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

我注意到這使得警報彈出兩次。我試圖做一些重構。該程序已經工作了一段時間,但我認爲回到它會很有趣,看看我可以如何改進它,因爲它是我的第一個程序。非常感謝你的幫助,我幾乎放棄了。目前的版本在github上https://gist.github.com/1861120。任何反饋或重構,將不勝感激。 – Justin

+0

我找不到任何問題。不錯的工作! – Blender

0

我寧願遞歸函數,尾遞歸可能導致計算器像斐波納契功能。

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

您也不應該將自己的函數添加到數學命名空間。這不是一個好習慣。

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