阶乘计算(用数组存结果)

如何计算一个很大的数的阶乘?
比如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;
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NLP饶了我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值