C语言:关于n的阶乘求和(包含n>20)

发布于:2022-10-21 ⋅ 阅读:(726) ⋅ 点赞:(0)

C语言关于n的阶乘求和我们可以多次使用循环完成,代码如下:

287022af20ec4b2b9e830bef0f6d2cf2.png

但是,再输入大于20的数字,如21我们就会发现,结果为负数(为了显示明显,我已将原来代码改为循环输入):

f62c86485866499c843e8537560b23da.png

出现负数的原因就是因为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为输入的数,具体如下:        

f6eba5e7ac7645afa09e079b8d797c42.png

将数组初始化,注意fac[0]初始值为1,我们通过最外层for实现阶乘,现在,解释f和s的意思:我们举此次问题第一次循环为例子(指i=1),开始的话我们就从数组fac下标为0开始相乘,但是此时除了首元素以为其他元素都是初始值0,这时循环相乘就会显得毫无意义,所以我们把有值(不为0,此说法不准确,因为后续计算其值可能为0,但此处只为读者方便理解)元素称谓已开辟的元素,那么f就是阶乘数组fac已开辟元素的最大下标,同理s就为求和数组sum已开辟的元素的最大下标,关于f,s数值的改变我们之后讲解

1db6b06bde994870804448e9a9b85809.png

 

该步骤表示:(i-1)!与变量i相乘,产生n!,代码具体含义可理解为将(i-1)!各各进制位分开,用其各各数位与i相乘,但此时分开相乘的话某一位的和可能>=10,所以我们采取以下方式:

 

229e8d7a663a457394bf3fb7f16e225c.png

该循环就是将阶乘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也是同理故后续不在解释)

5878357f82c44778a14f99e3b41fd2d5.png

该处这样写是为了避免阶乘位数(fac)高于和(sum)的位数,即f>s,否则会造成结果错误(不写的话在i=5时,会出错)

 

db544dfef39d462a9c8b336d24a30a5a.png此处是将下标相同的元素相加,即:       sum[0]+=fac[0],sum[1]+=fac[1]

可以理解为两个数的和等于,个位加个位,十位加十位,然后输出十位,个位,但此时分开相加的话某一位的和可能>=10,所以接下来(该步骤和前面意思相同)

a7a3560207fb42d38c047275832ca33c.png

该循环就是将阶乘sun的元素超过10的,将其十进制位的数和存放到下标比该元素下标大一的元素中

最后一步就是循环输出结果

1f553e5b47d14d26adca407a9c18e466.png

 

 

解题思路2: 我们记阶乘和为sum,fac为阶乘的值,number为输入的数,具体如下:

d7753b76263947de9523d7611e31da99.png将数组初始化,注意fac[0]初始值为1

da67570518a840a6855bd83aabddce9f.png

开始的话我们就从数组fac下标为0开始相乘,由于我们定义数组元素个数为100,而k=0,所以到k<100结束。该步骤表示:(i-1)!与变量i相乘,产生n!代码具体含义可理解为将(i-1)!各各进制位分开,用其各各数位与i相乘,但此时分开相乘的话某一位的和可能>=10,所以我们采取以下方式:

 

7d02cd0298954486bbd4a1d68408fe6b.png

该循环就是将阶乘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,如此循环。

下一步就是求和

c6edde4a8c4348938c3dcf33f48c1802.png

此处是将下标相同的元素相加,即:      sum[0]+=fac[0],sum[1]+=fac[1],可以理解为两个数的和等于,个位加个位,十位加十位,然后输出十位,个位,但此时分开相加的话某一位的和可能>=10,所以接下来(该步骤和前面意思相同)

21d20aebf57d4bde942945940c27ad44.png该循环就是将和数组sum的元素超过10的,将其十进制位的数和存放到下标比该元素下标大一的元素中

最后就是输出结果:

071c423fa6aa4dec843df72adcc8aae4.png

输出我们先输出高位上的数字,但是由于我们不知道从99-0哪一个下标存有数(有意义的数,就像number=1,sum=1,但是我们采用数组下标大的元素先输出,就会产生这样的效果--先输出99个0,最后输出1),所以我们先找到第一个不为0的下标,然后输出该下标和小于该下标的元素

 

现在我们验证我们的代码是否正确,我们使用Python编程来实现阶乘求和

7ba5e13b57dc4ecb984fd20851c75c5f.png

我们都入50

Python代码结果:

3d28e6ca9cef451197805b60235d78b3.png

思路一代码结果:

1f3fd64ddcfc4047b5278a13a39f6c3a.png

 

思路二代码结果:

f1c240ac2237489c9e39b51b71df581b.png思路一代码:

0e37931db28249dcb3400ed98416b32b.png

思路二代码:

438370c4b2594dc185103e5cff57cd5f.png

Python验证代码:

c9fb9354409e4cfe8ec5d19e9673e4d9.png

如读者感兴趣也可以改变fac和sum数据大小和类型实现更高数据的储存

 

笔者由于学资较浅在叙述过程中可能表达不明确或者有误,可在评论区指出或者私信本人

9398b95e19bc42be9d5a123c73fe2943.jpg

 

 

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到