2013-02-09 31 views
1

我正在嘗試在C中重新編寫這個bash函數,但有點不確定如何將此函數轉換爲C循環。轉換一個Bash函數來計算n!到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)))))) 
+0

階乘工作在標準整數類型的這麼少輸入整數的範圍,我會只是做一個查找表,而不是計算循環。無論如何,你必須檢查用戶輸入是否在界限內。 – 2013-02-09 10:30:49

回答

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

希望這有助於!

+0

非常非常!謝謝! – user1787331 2013-02-09 05:06:11

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

int main() 
{ 
    printf("%d", factorial(5)); 
    return 0; 
} 
+0

不應該是'int main()'?或者是'void main()'合法的C? – templatetypedef 2013-02-09 05:02:31

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