我有一个数学网站http://finitehelp.com,教授学生有限数学。 我认为包含一个计算器会很酷,所以我在Javascript中为组合和排列做了一个。实时计算器位于http://finitehelp.com/finite-calculator.html。我对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 :(得分: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=
代码。
答案 1 :(得分:4)
如果您担心效率,您可能希望将factorial重新实现为迭代函数而不是递归函数。递归版本将比迭代版本使用更多的内存和CPU时间。
function factorial(n) {
var x=1;
var f=1;
while (x<=n) {
f*=x; x++;
}
return f;
}
您也不应该将自己的函数添加到Math命名空间。进入不是一个好习惯。
答案 2 :(得分: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
答案 3 :(得分:0)
我更喜欢递归函数,tail递归可能会导致像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 :(得分:0)