優化階乘演算法的探索

2021-04-30 14:14:09 字數 3222 閱讀 7232

優化階乘演算法的探索

中國地質大學(武漢)   陳海豐

階乘(factorial)是基斯頓·卡曼(christian kramp, 1760 – 1826)於2023年發明的運算符號。階乘,也是數學裡的一種術語,是指從1乘以2乘以3乘以4一直乘到所要求的數。例如所要求的數是4,則階乘式是1×2×3×4,得到的積是24,24就是4的階乘。如果所要求的數是n,則階乘式是1×2×3×……×n,設得到的積是x,x就是n的階乘。在表示階乘時,就使用「!」來表示,如n階乘,就表示為n!。

根據階乘的定義,我們不難得到求解階乘的遞推式。

…………………………………(1)

當n值很小時,在計算機中可以直接用整型資料的運算就可以解決了,可是當n值很大,比如n=10000時計算結果就不能用現有的資料型別來存放了,因為它的位數已遠遠超過了現有的資料型別(如10000!有35660位)。為了解決所有資料型別都無法存放這樣乙個龐大的資料,目前大家採用的是將乙個大數一位一位的存放到乙個字元型陣列或整型陣列中,然後要運算時對其每一位進行單獨運算,這樣就解決了龐大資料的存放問題。但具體怎樣對兩個都比較大的數的作乘法運算呢?這就要利用大整數的高精度運算。如a,b都是位數比較多的大整數,現在要作a*b運算。小學時我們作45*12是先把12中的2與45的個位5相乘,再把2與45的十位4相乘,然後同樣再把12中的1與45中的每一位從低到高依次相乘。在這裡我們也可以模擬45*12,把a中每一位從低到高與b中的個位相乘,與後再與b中的十位相乘,依次類推,最後把所有的結果對應相加就可以得到所要求的結果了。

具體**(一):

#include

#include

char a[40000], b[10];

int c[40000];

int main()

//幾種特殊情況

if(n == 2)

a[0] = 50;   //初始化使是最先相乘的數從開始

for(k1 = 3;k1 <= n;k1++)

la = strlen(a);

lb = strlen(b);

memset(c, 0, sizeof(c));

for(i = 0;i < la;i++)

}

if(c[lc] == 0) lc--;

for(i = lc;i >= 0;i--)

for(i = lc;i >= 0;i--) a[i] = c[i] + 48;

//將結果複製到陣列a中,再和b陣列相乘

}

for(i = lc;i >= 0;i--)

printf("/n");

memset(a, 0, sizeof(a)); //將陣列全部初始化

memset(b, 0, sizeof(b));

}

return 0;

}

上面程式可以計算大數的階乘,但是效率非常的低,如10000!的階乘需要2000ms左右,所以這種演算法並不能解決實際問題。考慮到上面的程式是一位一位的把乙個大數存放下來,然後相乘時也是一位一位的進行的。然後我想到定義乙個整型的陣列,每一位不是存放一位而是存放五位,這樣相加,相乘的次數就是原來的 ,10000!運算時間是200ms,是原來的 。

具體**(二):

#include

int main()

, j, i, k = 0, t = 0, p = 0;

long sum = 0;

s[0] = 1;

for(j = 1;j <= n;j++)

}

else s[i]=sum;

}

}

printf("%d!=", n);

printf("%d", s[t]);

for(i = t - 1;i >= 0;i--)

printf("/n/n");

printf("請再輸入乙個整數n(0~20000):/n");

}

return 0;

}

當然在程式中可以把存放大數的陣列定義成長整型(long)則每乙個陣列元素可以存放更多位,10000!的執行時間可以縮短到50ms。在實踐中演算法的可行性是非常重要的,演算法要不斷的優化才能有機實際作用,所以要學會優化演算法,提高自己的程式設計能力。

Dijkstra演算法探索及優化

前幾天並多少時間,現在補充一下!下面是原始的dijkstra演算法 public static void dijkstra int v,float a,flaot dist,int prev 此處開始遍歷 dist v 0 s v true 該迴圈是求的所有節點到源節點的路徑,每迴圈一次求的乙個節點...

大數的階乘演算法

用data陣列來存放階乘的每一位數字,首先令第一位的數值為1,位數為1,然後將每次相乘的乘積存回陣列,並迴圈處理每個陣列中超過10的數,若數值超過10,則需要進製,將位數加1,原來的數除以10,商數加前一位數的數值後存回前一位數的陣列中,再將餘數存回原來位數的陣列中。例如求5!的值 步驟一 1!1 ...

階乘的快取演算法

階乘一般都是用遞迴的方式,但是在重複使用階乘的場景,就需要使用快取了,這樣就能提公升很大效率了。如下 include include include include using namespace std int n 6 int cache new int n 1 1.階乘方式 int factor...