上一篇说道用“/”和“%”这两种算法来将大数据的各个位上的数字存储在数组中,实现高精度加法问题。这一篇同样用这样的算法来实现阶乘的运算。
如果使用普通的算法,听说大概在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[N] = {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[N] = {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. 增加一个进位数的记录。