計算階乘升級版---pta測試基礎題
阿新 • • 發佈:2019-01-23
4-10 階乘計算升級版 (20分)
本題要求實現一個列印非負整數階乘的函式。
函式介面定義:
void Print_Factorial ( const int N );
其中N
是使用者傳入的引數,其值不超過1000。如果N
是非負整數,則該函式必須在一行中打印出N
!的值,否則列印“Invalid input”。
裁判測試程式樣例:
#include <stdio.h> void Print_Factorial ( const int N ); int main() { int N; scanf("%d", &N); Print_Factorial(N); return 0; } /* 你的程式碼將被嵌在這裡 */
輸入樣例:
15
輸出樣例:
1307674368000
這個題目要是用普通的迭代或者迴圈來計算階乘,線上評測的時候是不能通過的,原因是階乘的結果隨著n的增大急劇增大,當n大到一定數後即使是unsigned long型別也無法儲存結果,這時只能採取別的方法來儲存結果。主要思路如下:
1.開闢一個很大的整形陣列,如5000;
2.陣列的每一個元素只儲存計算結果中的一位數字,陣列索引最小的元素對應計算結果的最小位,依次類推;
3.對於從2至n 中的每一個數字x,陣列中的每一個數都要與x相乘,乘積仍儲存在該元素中,並判斷每一個元素中的數字是否超過10,若超過,則向前進位;
4.迴圈處理。
5.逆序輸出。
演算法過程:
以計算 5 的階乘為例,假設現在數組裡已經存放了計算好的 4 的階乘結果 2 4
(result[1] = 2, result[0] = 4)
,接下來要乘以 5。演算法過程即為,4 * 5 加上進數 carry(初始時 carry為 0),用 temp 儲存這個值。temp 取餘後放在 result[0] 中。temp 再除以 10,得到進數 carry,然後處理下一位。下一位操作當前位的操作是一致的。就這樣一致迴圈處理下去,直到沒有進位。
本質上是模擬手算的過程。
程式碼如下:
// // main.c // 計算階乘 // // #include <stdio.h> void Print_Factorial ( const int N ); int main(int argc, const char * argv[]) { // insert code here... int N; scanf("%d", &N); Print_Factorial(N); return 0; } void Print_Factorial ( const int N ) { if(N < 0) printf("Invalid input"); else if (N == 0) printf("1\n"); else{ int result[5000] = {0}; //儲存計算結果的陣列,每一位先初始化為0 result[0] = 1; //計算的初始值為1 int length = 1, carry = 0; //length表示當前結果的有效位數,carry表示進的數 int temp; for(int i=2; i<=N; i++){ //從2乘到n for(int j=0; j<length; j++){//結果集中的每一位都要與i相乘 temp = result[j] * i + carry; result[j] = temp%10; carry = temp/10; //獲得進位 //當有進位且已經處理到最前位時才開拓目標陣列的下一位 if(carry && j==length-1){ length++; } } } //逆序輸出結果陣列 for(int i=length-1; i>=0; i--){ printf("%d",result[i]); } printf("\n"); } }