编写程序求n!--C语言中数组的使用

来源:互联网 发布:淘宝开店论坛 编辑:程序博客网 时间:2024/05/22 04:42

注:部分内容摘自《数据结构》,黄国瑜,叶乃菁编著,清华大学出版社。

需求:编写程序求n!。

分析:数字相乘可以分解为各个阶位相乘,比如百位数A*B可分解为A100*B+A10*B+A1*B,然后从小位到大位分析,如果某一位的值大于等于10,则需要向高位进位,并对该位除以10,余数为该位的值。比如24*5,等价于(2*5)*10+(4*5)*1,因为4*5=20大于10,则从个位向十位进2,余0,这样十位为12(10+2),因为大于10,则十位须向百位进位1,余2为十位值,最后百位为1,十位为2,个位为0,即120,为最终计算值。每一位的表示可以使用整型值数组表示。

程序:

自己编写:

/** *功能:求解n! *作者:赵聪 *时间:2013-3-30 */#include <stdio.h>#define LEN 40//控制数据位数的数组长度/** *主程序 */int main(void){int num[LEN]={1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//保存数据的数组int factorial = 0;//阶乘nint p2top;//指向当前数组中的最高位int p2num;//指向数组位数的游标int index;//用于阶乘的索引值long long temp;//用于记录当前位的值int temp2left;//用于记录进位的位数long temp10;//用于计算除数值int tempindex2left;//计算除数时的索引值/** *输入阶乘n */ printf("Please input factorial number: ");while((scanf("%d",&factorial) != 1) || (factorial <0)){//输入错误或输入值为负数printf("Please input a positive number!\n");printf("Please input factorial number: ");}if(factorial == 0)//0的阶乘printf("%d!=1.",factorial);p2top=0;//初始化数组的最高位为0num[0]=1;//第一位为1for(index=1;index<=factorial;index++){//从1开始计算for(p2num=p2top; p2num>=0;p2num--)num[p2num] *= index;//有隐患,有可能每一位计算的时候就溢出,当然这种情况出现在很大的阶乘时,当前算法不一定适用for(p2num=0;p2num<=p2top;p2num++){//整理if(num[p2num]>=10){//如果当前位的值大于等于10,需要进位temp = num[p2num];temp2left = 0;while(temp>=10){//求需要进几位temp/=10;temp2left++;}if((p2num+temp2left)>=40){//如果进的最高位超过数组长度,报错误,并退出printf("阶乘值溢出,退出程序!\n");return 0;}else{if(p2top<(p2num+temp2left)){//如果进的最高位已经超过当前的最高位值,更新当前的最高位值p2top=p2num+temp2left;}while(temp2left>0){//分别向应该进位的地方,增加相应的值temp10=1;tempindex2left = temp2left;while(tempindex2left>0){//求增加相应的值时的除数temp10 *=10;tempindex2left--;}num[p2num+temp2left]+=num[p2num]/temp10;//增加相应的值num[p2num]%=temp10;temp2left--;}}num[p2num] %= 10;//当前位应留的值}}//打印当前阶乘值printf("%d! = ", index);for(p2num=p2top;p2num>=0;p2num--){printf("%d",num[p2num]);}printf("\n");}return 0;}

书中的代码[已更正书中错误]:

#include <stdio.h>void main(void){int Data[40];//存储数组int Digit;//位数int i,j,r,k;int N;//阶乘nfor(i=1;i<40+1;i++)Data[i-1]=0;Data[0]=1;Digit=1;printf("Enter a number what you want to calculus: ");scanf("%d",&N);for(i=1;i<N+1;i++){for(j=1;j<Digit+1;j++)//每一位运算Data[j-1]*=i;for(j=1;j<Digit+1;j++){if(Data[j-1]>=10)//如果当前位的值大于等于10{for(r=j;r<Digit+1;r++){if(Data[Digit-1]>=10)//最高位大于等于10时,位数加1Digit++;Data[r-1+1]+=Data[r-1]/10;//向前增加值Data[r-1]=Data[r-1]%10;//求余,即为当前位的值}}}printf("%d!= ", i);//打印for(k=Digit;k>0;k--)printf("%d",Data[k-1]);printf("\n");}}

结果[两个结果一致,只展示一个即可]:


心得:

1、我的代码和书中代码唯一的区别在于:我考虑了进位时有可能向前多位进位,不一定是前一位,有可能是前两位,前三位等等,而书中代码则未考虑这么细,统一向前一位进位,然后再由前一位向前前一位进位,以此类推。相比较而言,书中的代码比较合适,并且简练;

2、数学分析能力不行的话,算法肯定不行。

3、《数据结构》书中代码错误太多。

原创粉丝点击