解题笔记(38)——大整数阶乘计算

     问题描述:求一个整数 n 的阶乘,0 <= n <=5000。

     比如n = 50,结果为30414093201713378043612608166064768844377641568960512000000000000

     思路:从阶乘的定义出发,n! = n * (n-1) * (n-2) * ... * 2 * 1。由于 n 很大,基本的数据类型是无法存储的。不过,我们可以用一个整型数组来存放结果(包括中间结果),数组的每一个元素存放结果的一位,数组的第一个元素初始化为1。计算过程比较简单,将n, n-1, n-2, 1依次乘以当前值,也就是整型数组保存的值。最终打印结果即可。

     参考代码:

void CalN_Solution1(int n)
{
	int a[20000] = {1, 0}; //保存结果,包括中间结果
	int m = 0;
	for(; n; n--)   //依次乘以n, n-1, 1
	{
		int c = 0;  //进位值
		for(int i = 0; i <= m; i++) //中间结果乘以n
		{
			c += a[i] * n;   //先计算再考虑进位
			a[i] = c % 10;   //第i位的中间结果
			c /= 10;         //向上进位
		}
		for(; c; c /= 10)    //向上进位
			a[++m] = c%10;
	}
	for(; m >= 0; m--) //打印结果
		cout<<a[m];
	cout<<endl;
}

     上述程序中,整型数组的每一个元素仅仅表示结果的一位,浪费了不少空间。改进的方法是,让数组每个元素保存结果的四位,这样可以大大节省空间,代码修改如下。

void CalN_Solution2(int n)
{
	int a[5000] = {1, 0}; //保存结果,包括中间结果
	int m = 0;
	for(; n ; n--)   //依次乘以n, n-1, 1
	{
		int c = 0, i = 0;
		for(; i <= m ; i++)   //中间结果乘以n
		{
			c += a[i] * n;    //先计算再考虑进位
			a[i] = c % 10000; //第i位的中间结果,注意这里是模10000,用以表示4位数
			c /= 10000;       //向上进位
		}
		a[m+1] = c;          //最多进位1位,因此不必用循环
		if(c > 0)  
			m++;
	}

	cout<<a[m--];
	for(; m >= 0; m--)
		cout<<setw(4)<<setfill('0')<<a[m];
	cout<<endl;
}

        使用很简单,代码如下。

#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
	int n;
	cin>>n;
	CalN_Solution1(n);
	CalN_Solution2(n);
	return 0;
} 

       本人享有博客文章的版权,转载请标明出处 http://blog.csdn.net/wuzhekai1985


猜你喜欢

转载自blog.csdn.net/wuzhekai1985/article/details/6845868