最近看了一些关于求大数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;
}
运行结果图:最后一行是运行时间