用于查找二项式系数的Bash脚本

时间:2014-08-30 20:10:59

标签: bash function shell combinations factorial

我正在尝试为二项式系数生成函数。我正在使用nCk = n!/(k!(n-k)!)公式。

我现在的代码是:

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

但我收到错误,因为我可能会搞乱语法。

任何帮助?

2 个答案:

答案 0 :(得分:4)

错误在nCk函数中:

nCk() {
    echo $(( $(factorial $1) / ( $(factorial $2) * $(factorial $(($1-$2))) )  ))
}

您需要小心将每个子表达式括在$( )中,以便*之类的内容不被视为factorial函数的参数。请注意,我还更改了声明以使用更广泛兼容的函数语法。

正如@chepner在下面的评论中建议的那样,这不是计算二项式系数的最佳方法。其中一个原因是你需要计算阶乘,而阶乘非常快。我可以使用bash计算的最高阶乘是20!;任何更高的值都会导致整数溢出:

$ factorial 20
2432902008176640000
$ factorial 21
-4249290049419214848

other ways to calculate the binomial coefficient,不需要阶乘。下面的函数实现了其中一个:

nCk2() {
    num=1
    den=1
    for((i = 1; i <= $2; ++i)); do
        ((num *= $1 + 1 - i)) && ((den *= i))
    done
    echo $((num / den))
}

使用这种方法,可以计算更高n值的系数,而不会遇到整数溢出。作为一个令人愉快的副作用,该函数也比原始函数快得多,因为它没有多次调用递归函数。

答案 1 :(得分:1)

试试这个。问题在于调用子shell中的阶乘。

function nCk {
  echo $(($(factorial $1)/$(( $(factorial $2) * $(factorial $(($1-$2))) ))  ))
}