问题描述:求一个整数 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