问题描述
输入一个正整数n,输出n!的值。
其中n!=1*2*3*…*n。
其中n!=1*2*3*…*n。
算法描述
n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法。使用一个数组A来表示一个大整数a,A[0]表示a的个位,A[1]表示a的十位,依次类推。
将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。
将a乘以一个整数k变为将数组A的每一个元素都乘以k,请注意处理相应的进位。
首先将a设为1,然后乘2,乘3,当乘到n时,即得到了n!的值。
输入格式
输入包含一个正整数n,n<=1000。
输出格式
输出n!的准确值。
样例输入
10
样例输出
3628800
n的阶乘是不难,但是关键在于n取值太大,数据会溢出,不能用数据类型存储,所以只能把数据存在字符数组里面,再对字符数组进行
乘法运算,本来想到java的大数类可以直接解决这问题,但是感觉那样没有意义。解决问题的时候碰到点小插曲,至今还没有明白为什么
#include<stdio.h> #include<string.h> #include<stdlib.h> void calculate_mul(char *mul_1,char *mul_2,char *result)//两个字符数的乘法 { int i,j,k=0,off=-1,r=0; int temp0; for(i=strlen(mul_2)-1;i>=0;i--) { r=0; off++; k=0; for(j=strlen(mul_1)-1;j>=0;j--) { if(result[k+off]==0) { result[k+off]=((mul_1[j]-'0')*(mul_2[i]-'0')+r)%10+'0'; r=((mul_1[j]-'0')*(mul_2[i]-'0')+r)/10; } else { temp0=result[k+off]-'0'; result[k+off]=(result[k+off]-'0'+(mul_1[j]-'0')*(mul_2[i]-'0')+r)%10+'0'; r=(temp0+(mul_1[j]-'0')*(mul_2[i]-'0')+r)/10; } k++; } if(r!=0) { result[k+off]='0'+r; } } strrev(result); } void nn(char *str_nn) { int i,n; char r[3000]="1"; char tmp[3000]="1"; char tmp2[3000]="1"; n=atoi(str_nn); for(i=1;i<=n;i++) { strcpy(tmp,r); strcpy(r,"0"); strcpy(tmp2,"0"); itoa(i,tmp2,10); calculate_mul(tmp,tmp2,r); } printf("%s\n",r); } int main() { char str_n[10]={0}; scanf("%s",&str_n); nn(str_n); return 0; }
n<=7的时候都正确,但是n=8的时候,却出乎意料的输出了40720,8!=7!*8=5040*8=40320,调试半天还是没有调试看出问题所在。
第二天各种尝试改成下面,竟然成功了。
#include<stdio.h> #include<string.h> #include<stdlib.h> void calculate_mul(char *mul_1,char *mul_2,char *result)//两个字符数的乘法 { int i,j,k=0,off=-1,r=0; int temp0; for(i=strlen(mul_2)-1;i>=0;i--) { r=0; off++; k=0; for(j=strlen(mul_1)-1;j>=0;j--) { if(result[k+off]==0) { result[k+off]=((mul_1[j]-'0')*(mul_2[i]-'0')+r)%10+'0'; r=((mul_1[j]-'0')*(mul_2[i]-'0')+r)/10; } else { temp0=result[k+off]-'0'; result[k+off]=(result[k+off]-'0'+(mul_1[j]-'0')*(mul_2[i]-'0')+r)%10+'0'; r=(temp0+(mul_1[j]-'0')*(mul_2[i]-'0')+r)/10; } k++; } if(r!=0) { result[k+off]='0'+r; } } strrev(result); } void nn(char *str_nn) { int i,n; char r[3000]="1"; char tmp[3000]="1"; char tmp2[3000]="1"; n=atoi(str_nn); for(i=1;i<=n;i++) { memset(tmp,0,sizeof(tmp)); strcpy(tmp,r); memset(r,0,sizeof(r)); memset(tmp2,0,sizeof(tmp2)); itoa(i,tmp2,10); calculate_mul(tmp,tmp2,r); } printf("%s\n",r); } int main() { char str_n[10]={0}; scanf("%s",&str_n); nn(str_n); return 0; }