算法:高精度阶乘
问题描述:
输入一个正整数n,输出n!的值,这里的阶乘结果必须是完全准确的,每一位都需要被精确输出,而且这里的计算结果有可能会非常巨大,超过计算机中的任何数据类型。
阶乘的计算公式:n!=1*2*3*…*n。
解题思路:
对于高精度要求的计算,我们一般的思路是如何准确拆解并分析每一个最小元素,如何精确保存每一位元素,最终又如果把它们揉合成一个整体。
对于这一个问题,我们的首要思路是:
1. 把最大元素拿来做每位拆分,并存储进数组中。
2. 把每一次的乘数都和数组中的有效位分别相乘,然后统一进位处理。
3. 最后从数组首位开始寻找,直到找到第一位真正有效的输出数据(!=0 && !=-1),依次输出。
下面是这个问题的参考代码,代码中对于必要的步骤进行了相应的注释:
参考代码:
1 #include<stdio.h> 2 3 void BitMul(int* result,int top,int num); 4 int main(){ 5 int n,top=10000; 6 int result[top]; 7 scanf("%d",&n); 8 if(n==0) 9 { 10 printf("0"); 11 return 0; 12 } 13 14 int i=0,temp; 15 for(i=0;i<top;i++) 16 result[i]=-1; //初始化每位标志-1 17 int temp_num=n,temp_id=top; 18 while(temp_num) //正向拆分每一位 19 { 20 temp_id--; 21 result[temp_id]=temp_num%10; 22 temp_num/=10; 23 } 24 25 if(n>1) 26 { 27 while(n-1>1) //这里注意因为已经利用最大数进行了初始化。 28 { //所以从n-1开始计算 29 BitMul(result,top,n-1); 30 n--; 31 } 32 } 33 34 for(i=0;result[i]==-1||result[i]==0;i++); //进入真正的第一个非零位 35 for(;i<top;i++) 36 printf("%d",result[i]);//从第一位非零位开始真正输出 37 return 0; 38 } 39 40 void BitMul(int* result,int top,int num){ 41 int temp_top=top-1; //指向数组内存上界的真实地址 42 while(result[temp_top]!=-1) 43 { 44 result[temp_top]*=num; //每一位与数字相乘,不要着急进位 45 temp_top--; 46 } 47 temp_top=top-1; 48 while(result[temp_top]!=-1) 49 { 50 if(result[temp_top]>9) //根据不同情况依次进位 51 { 52 if(result[temp_top-1]==-1) //如果前一位为-1,代表没有任何操作过 53 result[temp_top-1]=result[temp_top]/10; 54 else 55 result[temp_top-1]+=(result[temp_top]/10); 56 result[temp_top]%=10; 57 } 58 temp_top--; 59 } 60 }