编程练习:阶乘

/*=========================================================================
#    FileName: factorial.c
# Description: 阶乘100!计算 (主要代码来自网络,自己只是稍作修改)
#  LastChange: 2012-06-02 21:23:51

   算法流程如下:
      ...      十万/万  	  	千/百 	   		十/个 
	              0*1      	     0*1      		 1*1
				  0*2      	     0*2      	     1*2
				  0*3	   	     0*3			 2*3
				  0*4	   	     0*4			 6*4
				  0*5	   	     0*5      	     24*5
				  0*6  	    (0+120/100)*6     (120%100)*6
				  0*7       (6+120/100)*7     (120%100)*7
				  0*8       (49+140/100)*8    (140%100)*8
			(0+400/100)*9   (400%100+320/100  (320%100)*9
			                      .
								  .
								  .

	  算法的逻辑是比较容易看出来的,就是将每次计算的结果按两位划分,划分出来的
  各个两位数分别与一个递增的数相乘,所得结果大于100则向更高的两位数进位。因此
  这种算法求值极限大约是2^(8*sizeof(data_type))/99.本下面算法实现用的data_type
  是long int,在本人电脑中是32位,故最大阶乘数是2^(8*4)/99 = 4338350804,本算法
  的问题还在于它无法动态分配内存,这可以用链表来实现。不过阶乘数一大,用链表实
  现的话额外的内存开销会比较大。相比数组不一定好到哪去。阶乘的位数可以用斯特林
  公式求,下面是实现代码来计算,此代码来自网络。

#include<stdio.h>  
#include<math.h>  
int main()  
{  
	long int n,result;  
	for(;scanf("%ld",&n)!=EOF;)  
	{  
	   if(n==1) result=1;  
	   else  
			result=(long)((log10(sqrt(4.0*acos(0.0)*n))+n*(log10(n)-log10(exp(1.0))))+1);  
	   printf("%ld\n",result);  
	}  
	return 0;  
}

=========================================================================*/

#include <stdio.h>
#include <math.h>

#define MAXLEN 100 /*假设做的是100的阶乘,自己可修改*/
#define MAXSUM 1000 /*用来存放阶乘结果的数组最大长度*/

int main()
{
	long int i, j, k, n, sum ;
	long int a[MAXSUM]; // a[i] 存入低两位,a[i+1] 存入高两位

	for( i = 0; i < MAXSUM; i++ ) a[i] = 0; //数组赋初值

	a[0] = 1;

    //确定阶乘结果保存到数组中,存到数组的第几个元素
	for( i = 1; i <= MAXLEN; i++ ) {
		for( j = MAXSUM - 1; j >= 0; j--) {
			if(a[j] != 0) {
				n = j + 1;
				break;
			}
		} 

		//对存入数组中的数进行乘法运算
		for(k = 0; k < n; k++) 
			a[k] = a[k] * i; 

		//乘法完成后进行进位
		for(k = 0; k < n; k++) {
			sum = a[k];
			if(sum / 100 > 0) {
				a[k] = sum % 100;
				a[k+1] = a[k+1] + sum / 100;
			}
		}
	}

    //打印完成的阶乘结果
	printf("%d! = ",MAXLEN);
	if(a[n] == 0) k = n - 1; 
	else k = n;
	for(i = k; i >= 0; i--) {
		if(a[i] >= 10) printf("%d",a[i]);
		//由于03在数组中只显示3故进行相关操作补足
		else if(i < k) printf("0%d",a[i]);
		//但最高两位不希望补足
		else printf("%d",a[i]);
	}
	printf("\n");
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值