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

来源:互联网 发布:ipad桌面图标整理软件 编辑:程序博客网 时间:2024/04/29 08:53

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


原创粉丝点击