1

この bash 関数を C で書き直そうとしていますが、この関数を 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 関数が自分自身を呼び出すことは完全に合法です。これはrecursionと呼ばれます。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 バージョンの方が好みですが、どちらも機能するはずです。残念ながら、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;
}

2 番目の質問に答えるには、計算の前に次の数学的変換を行って、不要な計算オーバーヘッドを節約することをお勧めします。

  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 に答える