如何计算一个很大的数的阶乘?
比如100!,long long也不可能存下这么大的数。
所以类比乘法运算思想,即上面的乘数乘以下面的乘数的各个位,比如算11的阶乘,算到11×3628800时,笔算是这样算的:
为什么把11放上面呢?
因为阶乘结果太大,基本数据类型根本存不下。比如算30!,结果是265252859812191058636308480000000,long long也存不下,但是按照上面这种思想,就可以转换为若干个小整型数做带进位的加法,需要仔细考虑的地方是:计算到最后一个数时,除了计算当前位和进位外,还需要计算最后一个数的十位、百位和千位(如果有),比如11×3628800,如上图,最后一个数是33,算完3+6之后,33的十位还需要带进位额外计算。
根据这种思想,可以写出如下代码(细节见注释):
#include<bits\stdc++.h>
#define MAX_L 10000
using namespace std;
int len;
vector<int> temp(MAX_L);
int jinwei;
//类比乘法思想,上面的乘数为i,下面的乘数为数组a,也就是说较小的乘数放上面,较大的乘数放下面
void multiple(int *a, int i, int index, bool flag) //参数含义:下乘数、上乘数、当前运算的下标、是否计算temp的标志
{
if (index < len && flag)//数组长为len,故计算len次,遍历到最后一个数时需要带进位继续计算,但是此时不用计算temp,比如11*362880,最后一个数是33,但是33的十位需要带进位继续计算,但是不用算temp
temp[index] = a[index] * i;
if (index == 0)
{
a[index] = (temp[index] % 10+jinwei ) % 10;
}
else if (index == 1) {
a[index] = (temp[index] % 10 + jinwei + temp[index - 1] % 100 / 10) % 10;
jinwei = (temp[index] % 10 + jinwei + temp[index - 1] % 100 / 10) % 100 / 10;
}
else if (index == 2) {
a[index] = (temp[index] % 10 + jinwei + temp[index - 1] % 100 / 10 + temp[index - 2] % 1000 / 100) % 10;
jinwei = (temp[index] % 10 + jinwei + temp[index - 1] % 100 / 10 + temp[index - 2] % 1000 / 100) % 100 / 10;
}
else
{
a[index] = (temp[index] % 10 + jinwei + temp[index - 1] % 100 / 10 + temp[index - 2] % 1000 / 100 + temp[index - 3] % 10000 / 1000) % 10;
jinwei = (temp[index] % 10 + jinwei + temp[index - 1] % 100 / 10 + temp[index - 2] % 1000 / 100 + temp[index - 3] % 10000 / 1000) % 100 / 10;
}
if (index < len - 1) //没有遍历到最后一个数,则继续遍历
multiple(a, i, index + 1, 1);
if (index == len - 1 && flag) //遍历到最后一个数时,如果最后一个数:temp[index]不止一位,那么就需要算完多的位,算额外的位时,flag已经置0,该判断不用再访问第二次
{
int x = temp[index];
while (x/10 != 0)
{
++len;
multiple(a, i, len-1, 0);
x /= 10;
}
if (jinwei) //算完最后一个temp之后如果还有进位,进位
{
++len;
a[len - 1] = jinwei;
}
}
}
int main()
{
while (1) {
len = 1;
int a[MAX_L] = { 0 };
int n; cin >> n;
a[0] = 1;
temp.assign(MAX_L, 0);
for (int i = 1; i <= n; i++)
{
jinwei = 0;
multiple(a, i, 0, 1);
}
cout << "结果为:";
for (int i = len - 1; i > -1; i--)
cout << a[i];
cout << endl;
}
system("pause");
return 0;
}
运行结果: