C语言关于n的阶乘求和我们可以多次使用循环完成,代码如下:
但是,再输入大于20的数字,如21我们就会发现,结果为负数(为了显示明显,我已将原来代码改为循环输入):
出现负数的原因就是因为sum的数远远超出long long的范围:(-9223372036854775807~~9223372036854775808)
所以,我们将采取新的方法存超大数据,笔者想到到方法就是采用数组来完成:
1. 首先来实现存储数据,比如1199,我们可以将两个数字储存在数组中,a[0]=99,a[1]=11,输出的时候先将下标大的数字输出,这就是存储的思路。
2. 下面我们就计算的思路,还是上述例子,1199*5,乘的处理就是各各进制位分别相乘,a[0]*=5,a[1]*=5,那么我们就会发现a[0]已经超出两位数了,这时我们的处理方式就是除法和取余具体算法如下: a[1]+=a[0]%100,a[0]/=100
但是,你会发现一些问题,比如数字109,我们若两位一存,数组a[0]=(0)9,a[1]=1,输出结果就为19,所以我们采取一位一存的方法,所以像119,我们就分别用三个变量储存其个位,十位,百位,在进行加减时我们各各位数分别相乘,然后当变量大于等于10是我们用取余和除法,其储存到比它大的数位中,如相乘后个位为11,用除法和取余,将表示十位的变量加1,个位取余后就变为1了,看出此过程需要多次使用循环,这就是本体主要思路。
解题思路1:(逻辑较强,体现在f,s的变换,若难以理解就跳转到思路2,且评判系统对计算时间不严格也可以采用思路2的代码,两种思路并无本质区别)我们记阶乘总和为sum,fac为阶乘的值,number为输入的数,具体如下:
将数组初始化,注意fac[0]初始值为1,我们通过最外层for实现阶乘,现在,解释f和s的意思:我们举此次问题第一次循环为例子(指i=1),开始的话我们就从数组fac下标为0开始相乘,但是此时除了首元素以为其他元素都是初始值0,这时循环相乘就会显得毫无意义,所以我们把有值(不为0,此说法不准确,因为后续计算其值可能为0,但此处只为读者方便理解)元素称谓已开辟的元素,那么f就是阶乘数组fac已开辟元素的最大下标,同理s就为求和数组sum已开辟的元素的最大下标,关于f,s数值的改变我们之后讲解
该步骤表示:(i-1)!与变量i相乘,产生n!,代码具体含义可理解为将(i-1)!各各进制位分开,用其各各数位与i相乘,但此时分开相乘的话某一位的和可能>=10,所以我们采取以下方式:
该循环就是将阶乘fac的元素超过10的,将其十进制位的数和存放到下标比该元素下标大一的元素中,此时此次我们举i=4,因为小于4的阶乘都是两位数(3!=9,4!=12)fac[0]=12,f=0,此时:
fac[0]>10,fac[1]+=fac[0],fac[0]/=10,
fac[1]=1,fac[0]=2,然后我们就开辟一个新的元素,所以f++,如此类推(s也是同理故后续不在解释)
该处这样写是为了避免阶乘位数(fac)高于和(sum)的位数,即f>s,否则会造成结果错误(不写的话在i=5时,会出错)
此处是将下标相同的元素相加,即: sum[0]+=fac[0],sum[1]+=fac[1]
可以理解为两个数的和等于,个位加个位,十位加十位,然后输出十位,个位,但此时分开相加的话某一位的和可能>=10,所以接下来(该步骤和前面意思相同)
该循环就是将阶乘sun的元素超过10的,将其十进制位的数和存放到下标比该元素下标大一的元素中
最后一步就是循环输出结果
解题思路2: 我们记阶乘和为sum,fac为阶乘的值,number为输入的数,具体如下:
将数组初始化,注意fac[0]初始值为1
开始的话我们就从数组fac下标为0开始相乘,由于我们定义数组元素个数为100,而k=0,所以到k<100结束。该步骤表示:(i-1)!与变量i相乘,产生n!代码具体含义可理解为将(i-1)!各各进制位分开,用其各各数位与i相乘,但此时分开相乘的话某一位的和可能>=10,所以我们采取以下方式:
该循环就是将阶乘fac的元素超过10的,将其十进制位的数和存放到下标比该元素下标大一的元素中,此次我们举i=4,因为小于4的阶乘都是两位数(3!=9,4!=12)fac[0]=12,f=0,此时:
fac[0]>10,fac[1]+=fac[0],fac[0]/=10,
fac[1]=1,fac[0]=2,如此循环。
下一步就是求和
此处是将下标相同的元素相加,即: sum[0]+=fac[0],sum[1]+=fac[1],可以理解为两个数的和等于,个位加个位,十位加十位,然后输出十位,个位,但此时分开相加的话某一位的和可能>=10,所以接下来(该步骤和前面意思相同)
该循环就是将和数组sum的元素超过10的,将其十进制位的数和存放到下标比该元素下标大一的元素中
最后就是输出结果:
输出我们先输出高位上的数字,但是由于我们不知道从99-0哪一个下标存有数(有意义的数,就像number=1,sum=1,但是我们采用数组下标大的元素先输出,就会产生这样的效果--先输出99个0,最后输出1),所以我们先找到第一个不为0的下标,然后输出该下标和小于该下标的元素
现在我们验证我们的代码是否正确,我们使用Python编程来实现阶乘求和
我们都入50
Python代码结果:
思路一代码结果:
思路二代码结果:
思路一代码:
思路二代码:
Python验证代码:
如读者感兴趣也可以改变fac和sum数据大小和类型实现更高数据的储存
笔者由于学资较浅在叙述过程中可能表达不明确或者有误,可在评论区指出或者私信本人
本文含有隐藏内容,请 开通VIP 后查看