也談大數階乘

2021-05-21 21:41:19 字數 1668 閱讀 8106

最近公司裡面的專案一直用c++來進行,基礎太薄弱,於是自己完成了公司的任務後,加緊練習。

本來那天是想寫乙個遞迴階乘演算法的,發現有不少問題啊:

第一: 遞迴有乙個弊端,就是棧空間不夠的問題

第二:遇到大數的時候,在cpp中沒有辦法找到合適的資料型別來進行計算,用long,double都是不可能夠的。因為我一開始的目標至少是要計算到1000的階乘的(現在想想實在太小)。

下面簡單說說實現的思路:

n!,對於任意的01)初始分配空間

假設定義 long* result = (long*)malloc(sizeof(long*n*q);其中的q我為了考慮足夠的空間,暫時取的是10(這個q的計算我尚未進行,所以在空間上是有浪費的)。用malloc來定義result,是考慮到大數的結果位數比較大,需要存放的空間會比較大,所以放在堆中(題外,對於堆疊儲存的理解也不知道對不對,最近公司裡面要我寫的**中有一段用了遞迴,於是公司的同事告訴我,遞迴可能會導致棧空間不夠,最好不要用遞迴,於是自己上網查了查,大概就這麼理解。不知道堆中最多能存放多少的空間呢?是不是記憶體有多少就能存多少?)。

2)核心演算法

for i: 1-n      //從1*2*3*4...n

int upvalue = 0;

for j: 0-result.size  //  假設result是712,那麼result[0]=2,result[1]=1,result[2]=7.然後計算下乙個result的時候,分別

// 每一位對i相乘,如果》10,再進製

int tmpvalue = resultm[j] * i + upvalue;   //將result當前位和i相乘後+進製,計算結果放在臨時變數tmpvalue中

resultm[j] = tmpvalue % 10;                    //當前位存放tmpvalue的個位數

upvalue = tmpvalue / 10;                        // 將tmpvalue/10後的數用於存放進製,供下次計算使用

//當result計算完成結束迴圈後,如果最後一位有進製,那麼result的位數就要增加,所以這裡就要對這個情況進行處理

while(upvalue != 0)

如此就算完成了。

3)改進

檢視結果可以發現,後面有若干個0.如果在for j: 0-result.size  這層迴圈裡面進行數個0*i,就很浪費時間了。

所以在for j: 0-result.size  迴圈前,判斷0的個數,初始zeronumber=-1:

while(result[zeronumber + 1] == 0)

然後將for j: 0-result.size  中,j的初始計算改為zeronumber+1,這樣效率就會提高不少。

4)原始碼

5)效果

我在公司的機器稍微好些,10000基本秒殺,100000基本在2分鐘左右計算完成。

我在家的機器配置稍差,我在虛擬機器中執行,1.96g cpu,256m記憶體,計算10000在5秒內,計算100000需要14分鐘以內

6)不足

cpu佔用率高,不知道程式設計的時候,有哪些會使得cpu佔用率高?要怎麼使cpu佔用率降低呢?

記憶體空間還存在有浪費情況。

效率還不夠高。

7)小結

對大數階乘的學習暫時告一段落了,等以後學的知識再多些,才能再進行改進了。

N的階乘 大數階乘

輸入n求n的階乘的準確值。input 輸入n 1 n 10000 output 輸出n的階乘 首先,要確定n的階乘的數字大概有多少位,這樣便於我們去選擇合適的演算法。階乘 當n 10000時,上式值為35660 已經向上取整 所以接受 include include include include ...

也談武媚娘

前段時間電視熱播 武媚娘 老婆天天晚上看。我不大喜歡看各種誇張和粉飾的歷史劇,但是對歷史還是喜歡一些,所以就利用閒餘的時間搜尋一下,看看唐朝的那些事。正好把自己的搜尋和感慨整理記錄下。唐朝是乙個中國發展的乙個鼎盛時期,即便如此,也是乙個多事的朝代。李世民宣武門弒兄,自己逼迫父親成為了太上皇,兒子李志...

大數階乘65!

include include define n 200 void sub int left int right int result 實現兩個大數相乘的演算法 乘得的結果是反序的,這樣保證假如前面是0的話也可以保留 for i 0 i 2 n i 上面乘出來的結果的陣列可能有些位數是超過10的,所...