1

我正在尝试用 C 重写这个 bash 函数,但是有点不确定如何将这个函数转换为 C 循环。

在这里,我设置了变量。这个我已经有了

n=10
r=4

这是我对如何重新编写它有点迷茫的地方。这似乎是用自己的函数调用函数,我很确定 C 不会那样做(至少安全)而且它根本不需要是一个函数,我只需要插入相同的变量并让它来出同样的结果。

factorial() {
if (($1)); then
    echo $(($1 * $(factorial $(($1-1)))))
else
    echo 1
fi
}

最后一点,用 C 语言表达以下代码的最佳方式是什么?bash 中的括号会延续吗?

result=$(($(factorial $n)/($(factorial $r)*$(factorial $(($n-$r))))))
4

3 回答 3

3

C 函数调用自己是完全合法的——这称为递归。在 C 中,它看起来像这样:

int factorial(int n) {
    if (n == 0) return 1;
    return n * factorial(n - 1);
}

您也可以直接将其编写为循环:

int factorial(int n) {
    int result = 1;
    for (int i = 1; i <= n; i++) {
        result *= i;
    }
    return result;
}

希望这可以帮助!

于 2013-02-09T05:02:13.960 回答
0
 int factorial(int i)
 {
    if(i)
       return factorial(i - 1) * i;
    return 1;
 }

 int main()
 {
     printf("%d", factorial(5));
     return 0;
 }
于 2013-02-09T05:01:45.770 回答
0

由于它涉及的函数调用开销要少得多,我更喜欢 non_recursive 版本,但它们都应该工作。我不知道 bash 如何处理大量数字,不幸的是,在 C 中 long double 是您在不使用外部库的情况下可以获得的最大范围。

long double recursive (int n) {
  if (n <= 1)
    return 1.0;
  else return (n * recursive (n-1));
}

long double non_recursive (int n) {
  long double value = 1.0;

  while (n > 1)
    value *= n--;

  return value;
}

要回答您的第二个问题,我建议在计算之前进行以下数学转换,以避免不必要的计算开销:

  n!               (M+1) * (M+2) * ... * n
-----------    =   ------------------------  
r! * (n-r)!             (n-m) !

                  with M = max (r, n-r), m = min (r, n-r);

鉴于这种转换,相应的 C 代码将如下所示:

long double over (int n, int r) {

  int M;
  int m;

  if  (r > n-r) {
    M = r+1;
    m = n-r;
  }
  else {
    M = n-r + 1;
    m = r;
  }

  long double value = 1.0;

  while (M <= n)
    value *= M++;

  while (m > 1)
    value /= m--;

  return value;
}
于 2013-02-09T05:35:26.890 回答