hba*_*ega 2 bash shell combinations function factorial
我正在尝试为二项式系数生成一个函数。我正在为此使用 nCk=n!/(k!(nk)!) 公式。
我目前的代码是:
function factorial {
typeset n=$1
(( n < 2 )) && echo 1 && return
echo $(( n * $(factorial $((n-1))) ))
}
function nCk {
echo $((factorial $1/$(( factorial $2 *factorial $(($1-$2)) )) ))
}
Run Code Online (Sandbox Code Playgroud)
但是我遇到了错误,因为我可能会弄乱语法。
错误在您的nCk函数中:
nCk() {
echo $(( $(factorial $1) / ( $(factorial $2) * $(factorial $(($1-$2))) ) ))
}
Run Code Online (Sandbox Code Playgroud)
您需要小心地将每个子表达式括起来,$( )以免将 之类的内容*视为factorial函数的参数。请注意,我还更改了声明以使用更广泛兼容的函数语法。
正如@chepner 在您问题下方的评论中所建议的那样,这不是计算二项式系数的最佳方法。原因之一是您需要计算阶乘,它会非常快地变得非常大。我可以使用 bash 计算的最高阶乘是20!; 任何更高的值都会导致整数溢出:
$ factorial 20
2432902008176640000
$ factorial 21
-4249290049419214848
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以计算二项式系数,不需要阶乘。下面的函数实现了其中之一:
nCk2() {
num=1
den=1
if (( $2 < $1 - $2 )); then
k=$2
else
k=$(( $1 - $2 ))
fi
for ((i = 1; i <= k; ++i)); do
((num *= $1 + 1 - i)) && ((den *= i))
done
echo $((num / den))
}
Run Code Online (Sandbox Code Playgroud)
使用这种方法,可以为更高的值计算系数,n而不会受到整数溢出的影响。作为一个令人愉快的副作用,该函数也比原始函数快得多,因为它不会多次调用递归函数。