思路
计算100阶乘,首先100的阶乘没有任何数据类型可以放下,所以只能用数组,每个元素记录一位数字。百度可以得到100的阶乘有158位,所以申请大小158的数组。
模仿竖式运算,用两个数组,一个数组用来不断乘结果,一个数组用来保存结果。需要两个循环,第一个循环生成1-100的数字,第二个循环用数组每一位乘这个数字
如345*5,需要用345每一位来乘5,先用个位5*5,个位需要填的数字是5,进位是2,然后用4*5,十位需要填0+进位,也就是2,然后继续进位2,所以每次保留的结果就是计算结果加上进位%10,进位就是结果/10
当计算到最后一位,也就是3*5,这个时候这一位填5,然后还有进位,这个进位需要保留到数组下一个元素去,所以需要一个下标cnt记录数组使用了多少位。当最后还有进位时,需要保存到cnt+1位,在循环累乘的过程中,这个进位很可能不只一位,所以需要循环处理,每次保留cnt%10,然后/10来更新进位,cnt每次也需要加一位。 例如: 进位时157,需要先在cnt+1位存7,由于数组下标从0开始,cnt就是当前数组的下一位下标,存完7吧157/10=15,cnt+1处%10存5,继续cnt+2存1
两个数组,每次更新一下用来计算的数组
特别注意,计算的数组第一位从1开始,因为0*任何数都是0,不能初始化0
代码
#include <stdio.h>
int main()
{
int ary1[158] = { 0 }; //保存的数组
int ary2[158] = { 1 }; //计算的数组
int cnt = 1; //数组位数
int carry = 0; //进位
int i = 1;
while (i <= 100) {
carry = 0;
//数组每一位乘i计算
for (int j = 0; j < cnt; j++) {
ary1[j] = (ary2[j] * i + carry) % 10;
carry = (ary2[j] * i + carry) / 10;
}
//最后有进位,往后存放
while (carry) {
ary1[cnt] = carry % 10;
carry = carry / 10;
cnt++;
}
//更新用来计算的数组
for (int j = 0; j < cnt; j++) {
ary2[j] = ary1[j];
}
i++;
}
//打印结果
for (int i = cnt - 1; i >= 0; i--) {
printf("%d", ary1[i]);
}
}
参数说明
ary1,存放数据的数组
ary2,用来计算的数组
cnt,数组使用的位数
carry,保存计算的进位
输出
该计算方法并不是最优解,只是比较直观的方法