一、问题描述:
计算阶乘n!是一件可怕的事情,因为当n并不是很大时,n!将是一个很大的值。例如13! = 6227020800,已经超过了我们常用的unsigned int类型的取值范围。
二、问题分析:
由于随着n的增大,n!迅速增大,因此,在计算n!时不能直接用整数表示计算结果,而要用字符串表示计算结果结果。因此需要解决用字符串表示的整数的乘法运算问题。
三、代码实现:
#include<iostream>
#include<cstdio>
#include<cstring>
void CalcNN(int n, char *pOut);
using namespace std;
int main(int argc,char **argv){
int n;
char pOut[1024];//此空间足以存储400以内的阶乘结果
cin>>n;
CalcNN(n,pOut);
cout<<pOut<<endl;
return 0;
}
static void myReverseStr(char *str){//反转字符串
char ch,*p=strlen(str)+str-1;
while(str<p){
ch=*str;
*str++=*p;
*p--=ch;
}
}
static void myBigNumberMultiply(char *operand1,char *operand2,char *result){
//大整数相乘,转化为大整数加法。
//输入:
// 乘数1:operand1
// 乘数2:operand2
//输出:
// 乘积结果的逆序:result,逆序输出方便连续操作。
int len1=strlen(operand1),len2=strlen(operand2);
memset(result,'\0',len1+len2+1);//初始化结果为0
myReverseStr(operand1);//逆置operand1以便于操作
char *p1=operand1,*p2,*p3;
int carry,temp;
while(*p1!='\0'){//将operand1的每一位分别与operand2相乘,并累加到结果中。
p2=operand2;
p3=result+(p1-operand1);
if(*p1!='0'){//operand1的该数位不为0则计算
carry=0;
while(*p2!='\0'){//与operand2的每一位相乘,并累加到结果中。
temp=carry+(*p3!='\0'?*p3-'0':0)+(*p2-'0')*(*p1-'0');
*p3='0'+temp%10;
carry=temp/10;
++p2;
++p3;
}
while(carry!=0){//处理进位
temp=carry+(*p3!='\0'?*p3-'0':0);
*p3='0'+temp%10;
carry=temp/10;
++p3;
}
}else if(*p3=='\0'){//operand1的该数位为0,result的该数位若有值则值不变,否则置为0
*p3='0';
}
++p1;
}
}
void CalcNN(int n, char *pOut){
char operand1[32],operand2[1024];
sprintf(pOut,"1");
int i=1;
while(++i<=n){
sprintf(operand1,"%d",i);
sprintf(operand2,"%s",pOut);
myBigNumberMultiply(operand1,operand2,pOut);
}
myReverseStr(pOut);//将最终结果调为正序
}
四、测试结果:
输入:
400
输出:
64034522846623895262347970319503005850702583026002959458684445942802397169186831
43627847864746326467629435057503585681084829816288351743522896198864680299793734
16541508381624264619423523070462443250151144486708906627739149181173319559964407
09549671345290477020322434911210797593280795101545372667251627877890009349763765
71032635033153396534986838683133935202437378815778679150631185870261827016981974
00629830253085912983461622723045583395207596115053022360868104332972551948526744
32232438669948422404232599805551610635942376961399231917134063858996537970147827
20660632021737947201032135662461380907794230459736069956759583609615871512991382
22865785795493616176544804532220078258184008484364155912294542753848035583745180
22675900061399560145595206127211192918105032491008000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000