<谭> 6.7
一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如,6的因子为1、2、3,而6=1+2+3,因此6是"完数"。编程找出1000之内的所有完数,并按下面格式输出其因子:
6 Its factors are 1,2,3
#include <stdio.h>
const int M = 1000; /* 定义寻找范围 */
int main()
{
int k1, k2, k3, k4, k5, k6, k7, k8, k9, k10;
int i, a, n, s;
for (a = 2; a <= M; a++)
{
n = 0; /* n累计因子的个数 */
s = a; /* s存放未求出的因子之和,初值为被测数本身 */
for (i = 1; i < a; i++)
if (a % i == 0) /* 由i到a循环检测i是否为a的因子 */
{
n++; /* 找到一个因子 */
s = s - i; /* 减去已找到的因子 */
switch (n) /* 将找到的因子赋绐k1, k2, ... */
{
case 1 : k1 = i; break;
case 2 : k2 = i; break;
case 3 : k3 = i; break;
case 4 : k4 = i; break;
case 5 : k5 = i; break;
case 6 : k6 = i; break;
case 7 : k7 = i; break;
case 8 : k8 = i; break;
case 9 : k9 = i; break;
case 10 : k10 = i; break;
}
}
if (s == 0) /* 已经找到全部因子 */
{
printf("%d Its factors are ", a);
if (n > 1) printf("%d,%d", k1, k2); /* n>1表示a至少有2个因子 */
if (n > 2) printf(",%d", k3); /* 注意以下if的用法,追加的方法 */
if (n > 3) printf(",%d", k4);
if (n > 4) printf(",%d", k5);
if (n > 5) printf(",%d", k6);
if (n > 6) printf(",%d", k7);
if (n > 7) printf(",%d", k8);
if (n > 8) printf(",%d", k9);
if (n > 9) printf(",%d", k10);
printf("\n");
}
}
return 0;
}
运行结果:
======================================================
6 Its factors are 1,2,3
28 Its factors are 1,2,4,7,14
496 Its factors are 1,2,4,8,16,31,62,124,248
======================================================
★ 显然这是一种比较繁琐的方法, 其中的开关语句switch用的有些牵强, 因为因子数的个数是不确定的, 通过预置10个,本题可以,可如果要验证更多时便无法确定, 一味增加它的个数也不是办法。书上还提到了用数组的方法更简单,不过只是用一个数组放k[11]来存放因子,这个11仍是人为预置的,和上述方法类似,只是形式上的简单而已,虽然对于本题来说没必要动态申请之类的,但我并不认为这是个好办法。虽然我没有更好的办法 ^_^
#include <stdio.h>
const int M = 1000;
int main()
{
int k[11];
int i, a, n, s;
for (a = 2; a <= M; a++)
{
n = 0;
s = a;
for (i = 1; i < a; i++)
if (a % i == 0)
{
n++;
s = s - i;
k[n] = i;
}
if (s == 0)
{
printf("%d Its factors are ", a);
for (i = 1; i < n; i++)
printf("%d,", k[i]);
printf("%d\n", k[n]);
}
}
return 0;
}
结果同上。
★
#include <stdio.h>
const int M = 1000;
int main()
{
int m, s, i;
for (m = 2; m < M; m++)
{
s = 0; /* s为因子之和 */
for (i = 1; i < m; i++)
if ((m % i) ==0) s = s + i; /* i为因子 */
if (s == m)
{
printf("%d Its factors are ", m);
for (i = 1; i < m; i++)
if (m % i == 0) printf("%d,", i);
printf("\n");
}
}
return 0;
}
运行结果:
======================================================
6 Its factors are 1,2,3,
28 Its factors are 1,2,4,7,14,
496 Its factors are 1,2,4,8,16,31,62,124,248,
======================================================
★ 比题目要求的多了个",", 当然和程序功能没啥关系啦, 如果非得要用题目的方式的话还要改的繁琐点, 加个计数器k, 第一次找因子循环时,记下因子的个数k, 输出的时候先输出k-1个因子,最后一个因子单独输出,就是为了最后那个逗号,没啥意义……
#include <stdio.h>
const int M = 1000;
int main()
{
int m, s, i;
for (m = 2; m < M; m++)
{
int k = 0, t = 0;
s = 0; /* s为因子之和 */
for (i = 1; i < m; i++)
if ((m % i) ==0)
{
s = s + i; /* i为因子 */
k++;
}
if (s == m)
{
printf("%d Its factors are ", m); /* 可在此输出因子的个数k */
for (i = 1; i < m; i++)
if (m % i == 0)
{
t++;
if (t < k) /* 通过两次计数比较区分最后一个因子 */
printf("%d,", i);
else
t = i; /* 最后一个因子赋给t, 此时t失去本意 */
}
printf("%d\n", t);
}
}
return 0;
}
运行结果:
======================================================
6 Its factors are 1,2,3
28 Its factors are 1,2,4,7,14
496 Its factors are 1,2,4,8,16,31,62,124,248
======================================================
评论