我们已知一个正整数如果等于它各位数字的阶乘之和,那么这个数字就是阶乘和数。接下来我将尝试只通过for循环编写代码来输出一千以内的所有三位阶乘合数。
为了达成这个目的,我们需要用for循环来处理100到999之中的每个数字。我们要在for循环中提取出每一个三位数的个位,十位,百位的数字,并求出每个数字的阶乘,最后把他们加起来与原来的数字相比较。
我们使用i来表示要处理的数字。要提取个位,十位,百位,我们应该使用这样的代码:
a = i % 10;
b = (i % 100 - i % 10) / 10;
c = (i - i % 100) / 100;
接下来我们通过在for循环中再度嵌套一个for循环来求个位,十位,百位的阶乘,用s1来表示a这个数字的阶乘结果,我们应该使用这样的代码:
for (; a >= 1; a--)
{
s1 = s1 * a;
}
通过让a不断地乘以减少的自己所求得的这个结果被s1记录下来,我们就得到了a这个数字的阶乘。
将同样的代码复制两遍,我们就可以求出来b和c的数字的阶乘,分别用s2,s3,来表示。
最后我们将s1,s2,s3加在一起,用e来表示这个数字的和,并通过一个简单的if来判断e是否和i相等,若相等,则输出该数字。我们应该使用这样的代码:
e = s1 + s2 + s3;
if (i == e)
printf("%d\n", i);
else
continue;
在这里插入一个continue可以加快循环,也可以把continue删除。
将以上的代码组合在一起,我们得到的代码如下:
#include <stdio.h>
void main()
{
int i, a, b, c, e;
int s1 = 1, s2 = 1, s3 = 1;
for (i = 100; i < 1000; i++)
{
a = i % 10;
b = (i % 100 - i % 10) / 10;
c = (i - i % 100) / 100;
for (; a >= 1; a--)
{
s1 = s1 * a;
}
for (; b >= 1; b--)
{
s2 = s2 * b;
}
for (;c >= 1; c--)
{
s3 = s3 * c;
}
e = s1 + s2 + s3;
if (i == e)
printf("%d\n", i);
else
continue;
}
此时,若运行代码,得到的结果将是无。程序运算的结果是三位数没有符合条件的阶乘和数。这与现实不符,代码没有报错,那必然是遗漏了什么关键的地方。
我重头开始排查,意识到了,我原来的代码中的,s1,s2,s3这三个应当只代表当前数字的个位,十位,百位的阶乘的数字,他们在上一个for循环中得到的结果会被带往下一个for循环,继续乘下去。也就是说,s1,s2,s3所代表的数字将越来越大,最后会超过int类型的最大值2147483647,这使得他们代表的数字与当前数字的个位,十位,百位的阶乘的数字并不相符,自然无法得到正确的结果。
若想要解决这个问题,我们只需要,在if之前将s1,s2,s3重新赋值为1就好。
修改后的代码如下:
#include <stdio.h>
void main()
{
int i, a, b, c, e;
int s1 = 1, s2 = 1, s3 = 1;
for (i = 100; i < 1000; i++)
{
a = i % 10;
b = (i % 100 - i % 10) / 10;
c = (i - i % 100) / 100;
for (; a >= 1; a--)
{
s1 = s1 * a;
}
for (; b >= 1; b--)
{
s2 = s2 * b;
}
for (;c >= 1; c--)
{
s3 = s3 * c;
}
e = s1 + s2 + s3;
s1 = 1;
s2 = 1;
s3 = 1;
if (i == e)
printf("%d\n", i);
else
continue;
}
此时运行代码,我们将得到符合阶乘和数的数字:145。
三位数中只有145是阶乘和数。