您的位置:首页 > 其它

高精度运算之阶乘

2014-01-24 18:28 169 查看
上一篇说道用“/”和“%”这两种算法来将大数据的各个位上的数字存储在数组中,实现高精度加法问题。这一篇同样用这样的算法来实现阶乘的运算。

如果使用普通的算法,听说大概在n=16的时候就开始出错了。所以当题目所给要求是给的n的范围是0到10000的时候,就应该果断采用高精度运算。

分析:

1.      阶乘

2.      多组数据输入

3.      高精度运算

普通的阶乘代码如下:

#include<stdio.h>
int main()
{
int n,i,f=1;
scanf("%d",&n);
if(n==0) printf("0");
else
for(i=1;i<=n;i++)
f=f*i;
printf("%d\n",f);
return 0;
}


 

基本算法就是,从1开始,让i作为变量,限制循环次数,到n。当然,对特殊情况n=0的处理要有。代码如下:

 

#include <stdio.h>
#define N 35661
/* 10000! 为35660位 */
int main()
{
int n, i, j, s, up,count;
int f
= {0};
while(scanf("%d", &n)!=EOF)
{
if(n==0) printf("0\n");
else
{
f[0] = 1;//需要刷新的数据的初始化放在循环里面
count =1;//用在输出时for语句中的第二个语句中。
for (i = 1; i <= n; i++)  /*外循环控制阶乘的数 */
{
up=0;//代表进位值
for (j=0; j < count; j++)  /* 内循环用于得出前一个数的阶乘结果乘以当前数i得出的阶乘结果   */
{
s = f[j] * i + up;
f[j] = s % 10;
up = s / 10;
}
while(up)   /*  记录进位  */
{
f[count++]=up%10;//相当于f[count]=up%10;count++;
up/=10;
}
}//这个过程在VC++6.0的环境下用F10调试,辅助理解
for (i = count-1; i >=0; i--) printf("%d", f[i]) ;//因为count最后一步也是执行了自加1的,所以实际上f[ ]总共有count-1个元素,即输出从i=count-1开始的。
printf("\n");
}
}
return 0;
}


 

在这个题的代码中,count起到关键作用,这个变量用来记录阶乘结果有几位数,并且初值为1,只有当up不位0((while(up)即while(up!=0))也就是需要往前进位的时候,count自加1,说明多了一位。(再细节的东西在代码后面的注释中应该很清晰了)

 

 

在这个代码之前,还写了这样一个代码,错误很多,不过还是值得拿上来说一下的。

#include <stdio.h>
#define N 5000
int main()
{
int n, i, j, s, up;
while(scanf("%d", &n)!=EOF)
{
int f
= {0};
f[0] = 1;
for (i = 2; i <= n; i++)//外循环控制阶乘的数
{
up=0;
for (j=0; j < N; j++) //内循环用于得出前一个数的阶乘结果乘以当前数i得出的阶乘结果
{
s = f[j] * i + up;
f[j] = s % 10;
up = s / 10;
}
//与前面的代码相比,下面少一段记录进位的代码
}
for (i = N-1; f[i] == 0; i--) ;
for (; i >= 0; i--) printf("%d", f[i]) ;//这两个for语句的意思是:从f[5000-1]开始找到第一个不是0的,开始输出,直到输到f[0]
printf("\n");
}
return 0;
}


这段代码的缺点有以下两点:

1.      定义一个有5000个元素的数组用于保存阶乘结果各个位上的数字。但是由于在一开始就没有注意到题目要求是从0到10000,所以开的数组太小。这属于空间的错误。

2.      没有像上面的代码中有一个方便写for语句的ount,而直接从第N个开始进行进位的处理,是非常浪费时间。这属于时间的错误。

3.      少了一段代码,没有进一步的进位的记录

改进

1. 10000 !算得的数有35660位,所以预处理时N为35661

2. 增加一个计数变量count,便于控制条件的写出

3. 增加一个进位数的记录。

来自优秀学长的总结:http://blog.csdn.net/lulipeng_cpp/article/details/7381346



 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息