大数的阶乘---可求1000!的值,位数,还可求数中2的个数(1个数组 简单易理解)

/*
求1000!的值,值中2的个数,阶乘值的位数
  大数的阶乘    
 
分析:阶乘的定义就是n! = (n-1)!*n,但是有基本的初始条件的,即0! = 1 
因此1! = 1*0! = 1 * 1 = 1;  2! = 2*1! = 2 * 1 = 2;     
依次类推,但是当n足够大时,整型根本无法装下n的阶乘,
如果用C++语言的整型或浮点型变量来实现的话,根本不可能,会产生溢出

阶乘也无非是乘法和加法罢了,如4!= 24;
可以用数组来存各位,数组的起始长度是1,每当遇到超过长度时,就自加1,
不过这里要稍微处理下的,以倒过来存,以便做乘法的,可以这样来存。
 4!  存  4  2  此时4!的长度为24的长度2
 5!  =  5 * 4!,可以用5去乘以4等于20,20取余20%10=0,如果大于10则需向高位进位5*4/10,下一位的结果就等于下一位乘以5*2加上刚才的进位得12,12对10余2保存,12整除10得1 最后移位反过来存0 2 1
 5! 存 0 2 1   此时5!的长度为120的长度3
 6! =6*5!  6*0=0 在对10取余的0 保存,无进位,然后6*2=12,12对10整除=1作为进位数,12对10取余=2保存,最后6*1+1(上一次的进位)=7保存   最后保存0 2 7
  6! 存 0 2 7  此时5!的长度为720的长度3
 ....依次类推
 1000!=1000*999! 

*/
#include <iostream>
using namespace std; 
#define N 1000         // 所需求的N的阶乘
static int a[N*3];     // 保存阶乘的各位,从a[1]开始存储,方向存放阶乘值,输出时倒序输出
int main()
{   
   int i,j;      //循环控制变量  
   int len = 1; //阶乘值的位数
   int tem,carry; //tem为乘积加进位值,carry为上次乘积的进位值
   int count_2=0;//记录阶乘值中2的个数
   a[1] = 1;     //1的阶乘   
   for (i = 2;i<=N;i++)    //求阶乘的方法   
   {   carry = 0;  //新一轮乘积要将进位重新置0
      for (j=1;j<=len;j++)   
	  {    tem = a[j]*i +carry;    
           a[j] = tem%10;  //获取乘积余数存放到对应数组位置
           carry = tem/10;  //获取乘积对10的整除值作为下一次计算tem计算的进位值
          if (j==len&&carry!=0)  //当乘到最后1位(乘积+进位数)超过10,即当乘到最后还有进位时,阶乘值的位数增1 
		  {     len++;    }  
	  }      
   } 
   for (i = len;i>=1;i--) //输出各位,逆序输出 
   {   
	   cout<<a[i];  
	   if(a[i]==2)
		   count_2++;
   } 
   cout<<endl; 
   cout<<N<<"的阶乘共 "<<len<<"位"<<endl;
   cout<<N<<"!中2的个数为:"<<count_2<<endl;
   return 0;
 }



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值