最近看了一些關于求大數N的階乘的方法,有點心得,特書寫出來,共同交流。題目:輸入一個正整數N,輸出N的階乘。N的範圍是0-1000.1000的階乘位數有兩三千位,顯然是很驚人的大資料。最開始,想到的是用字元串來表示,然後實作出字元串的加法和乘法。這樣用char[5000]足可以表示結果,占用記憶體也隻是40KB而已。但要實作字元串的乘法,比較繁瑣耗時,是以有點不太可取。後來看到網上有很多解法,其中比較常見的是用數組來表示結果,比如用int a[10000]來存放結果,輸出時依次按位輸出即可,但因每位上隻表示0-9,大大浪費了int型表示的空間(2^32=4*10^9。是以可考慮大進制數表示,比如10000.(之是以選擇10000,是因為考慮到兩個小于10000的數相乘不會超過int型表示的最大範圍)。這樣做,會大大節省記憶體,求1000的階乘,隻需要記憶體int a[500],2KB即可。
代碼如下:
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <Windows.h>
using namespace std;
void PrintNum(int num)//對于不夠四位的要補零
{
if (num>999)
{
printf("%d",num);
}
else
{
if (num==0)
{
for(int i=0;i<4;i++)
{
printf("%d",0);
}
}
else
{
int iCount=0;
int curentNum=num;
while(curentNum)
{
iCount++;
curentNum/=10;
}
for(int i=0;i<4-iCount;i++)
{
printf("%d",0);
}
printf("%d",num);
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
//用10000進制進行表示
int a[500];
int n;
int i,j;
LONG64 itime=GetTickCount();
while(scanf("%d",&n)!=EOF)
{
if(!n)
{
printf("1\n");
continue;
}
memset(a,0,sizeof(a));
int len=1;
a[1]=1;
for(i=1;i<=n;i++)
{
for(j=1;j<=len;j++)
{
a[j]*=i;
}
for(j=1;j<=len;j++)
{
if (a[j]>9999)
{
if (j==len)
{
len++;
}
a[j+1]+=a[j]/10000;
a[j]%=10000;
}
}
}
printf("%d",a[len]);
for(i=len-1;i>=1;i--)
{
PrintNum(a[i]);//進行補零輸出
}
cout<<endl;
int iRuntime=GetTickCount()-itime;
cout<<iRuntime<<endl;
}
return 0;
}
運作結果圖:最後一行是運作時間
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICO2kjNyIDN2ETOwkDMzEDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)