C !!史上最全!! 大數階乘N!

2021-09-26 09:27:21 字數 3795 閱讀 5842

在刷題的時候被小小的階乘卡住了,記錄一下自己走的彎路吧 !

我們知道 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 可以看成是每次兩個整數相乘的過程,因此可以模擬成大數相乘的過程。只是需要增加一些...