在刷題的時候被小小的階乘卡住了,記錄一下自己走的彎路吧 !
我們知道 int 的取值範圍是 -2147183648 ~ +2147183648(即-231~+(231-1)),大致範圍為-2×109 ~2×109 ,則用int最多只能存放 12!= 479001600(13!= 6227020800)。
而 long long的取值範圍是 -263~+(263-1)),大致範圍為-9×1018 ~ 9×1018 ,則用int最多只能存放 20!= 2432902008176640000(21!= 51090942171709440000)。
實現小數階乘的方法有以下幾種:
該程式在每次輸入n時,都會呼叫fac()來暴力計算以得到結果。
//************ 小數階乘---暴力法 ****************
#include
using namespace std;
intfac
(int n)
return facresult;
}int
main()
return0;
}
用陣列記錄已經計算得到的結果,避免重複計算,節省了時間但是消耗了記憶體。
//************ 小數階乘---陣列記錄法 ****************
#include
#include
using namespace std;
vector<
int>
facvec(2
,1);
intfac
(int n)
return facvec[n];}
intmain()...
用靜態變數儲存已經計算得到的結果,節省計算時間,也節省了記憶體,但是在順序輸入或者只計算一次的情況下會比較節省時間,如果隨機無限次計算階乘的話,陣列記錄法更快。
//************ 小數階乘---靜態變數法 ****************
#include
#include
using namespace std;
intfac
(int n)
static
int facres =1;
//用於記錄計算結果
static
int faccnt =1;
//用於記錄階乘變數
while
(n > faccnt)
return facres;
}int
main()...
看起來最簡潔的辦法,可以將上面兩種方法結合進來
//************ 小數階乘---靜態變數法 ****************
#include
using namespace std;
intfac
(int n)
else
}int
main()...
以上全都是用來計算小數階乘的辦法,如果超出範圍,會發成錯誤,實驗結果如下:
階乘結果定義為int型時,在計算 13! 時發生錯誤;
階乘結果定義為long long型時,在計算 21! 時發生錯誤;
在計算20!以上的數值,就不能使用以上方法了,就需要考慮其他存放資料的方法,我們常用的存放大數的方法有 使用字串儲存和使用數值儲存。
1.1. 字串儲存初級版
#include
#include
using namespace std;
string mutiple
(string num1,
int num2)
while
(c)return res;
}string fac
(int n)
// 遞迴函式
else
}int
main()
return0;
}
1.2. 字串儲存公升級版
初級版使用暴力法遞迴計算遞迴結果,使用陣列記錄法減少重複計算。
#include
#include
#include
using namespace std;
vector
nvec(2
,"1");
string mutiple
(string num1,
int num2)
string fac
(int x)
//遞迴函式
return nvec[x];}
intmain()
但是依然沒有達到要求的運算速度,考慮之後發現,使用字串儲存大數會花費很多時間在型別轉換上,這些過程十分的耗時,於是考慮使用陣列存放大數。
2.1 陣列儲存初級版
#include
#include
using namespace std;
vector
int>>
nvec(2
,vector<
int>(1
,1))
;void
mutiple
(vector<
int> num1,
int num2)
while
(c) nvec.
push_back
(res);}
void
coutvec
(vector<
int> numplus)
// 倒序輸出
cout<<
::endl;
}vector<
int>
fac(
int x)
return nvec[x];}
intmain()
return0;
}
2.2 陣列儲存公升級版
初級版終於滿足了執行時間的要求,但是執行記憶體不達標。觀察發現,並不需要將計算的所有結果都進行儲存,只需要保留最後的計算結果就可以了。
#include
#include
using namespace std;
vector<
int>
nvec(1
,1);
int lastn =1;
void
mutiple
(vector<
int> num1,
int num2)
while
(c) nvec = res;
}void
coutvec
(vector<
int> numplus)
cout<<
::endl;
}vector<
int>
fac(
int x)
while
(x > lastn)
return nvec;
}int
main()
return0;
}
終於達到預期要求,完結撒花。 N (大數階乘)
given an integer n 0 n 10000 your task is to calculate n input one n in one line,process to the end of file.output for each n,output n in one line.sam...
N的階乘 大數階乘
輸入n求n的階乘的準確值。input 輸入n 1 n 10000 output 輸出n的階乘 首先,要確定n的階乘的數字大概有多少位,這樣便於我們去選擇合適的演算法。階乘 當n 10000時,上式值為35660 已經向上取整 所以接受 include include include include ...
大數n的階乘
求算n 對於比較小的n,求其階乘的時候可以用遞迴解決。但是如果n很大的時候,比如1000,那麼n 肯定超出整形資料所能表示的範圍。因此必須採用其它方法解決,通常解決大數運算資料超出範圍的問題時採用陣列去模擬。其實求算n 可以看成是每次兩個整數相乘的過程,因此可以模擬成大數相乘的過程。只是需要增加一些...