关于除数和完美数字的棘手和令人困惑的C程序

时间:2014-11-06 18:40:42

标签: c

作业是:

编写一个程序,用于计算输入数字除数的总和。

如果一个数字的总和与数字相等(例如:6 = 1 + 2 + 3; 28 = 1 + 2 + 4 + 7 +14),则该数字被认为是完美的。

另一个定义: 一个完美的数字是所有正因子(包括其本身)总和的一半

生成前k个完美数字(k <150)。

这个问题的主要问题在于它使两个问题点之间没有真正的联系。

在这个程序中,我计算了输入数字的除数之和,但我不知道如何将它与第二个点相关联(生成前k个完美数字(k <150))。

#include <stdio.h>
#include <stdlib.h>


main()
{
int x,i,y,div,suma,k;
printf("Introduceti numarul\n");          \\enter the number
scanf("%d",&x);
suma=0;                                   \\sum is 0
for(i=1;i<=x;i++)
{

if(x%i==0)
suma=suma+i;                \\sum=sum+i;
}
printf("Suma divizorilor naturali este: %d\n",suma);      \\the sum of the divisors is

for(k=1;k<150;k++)               \\ bad part
{
if (x==suma)
printf("%d",k);
}
}

3 个答案:

答案 0 :(得分:1)

假设您有一个函数可以判断给定的整数是否完美:

int isPerfect(int);

(功能体未显示)

现在您的主程序将如下所示:

int candidate;
int perfectNumbers;

for(candidate = 1, perfectNumbers = 0; perfectNumbers < 150; candidate++) {
  if (isPerfect(candidate)) {
    printf("Number %d is perfect\n", candidate);
    perfectNumbers++;
  }
}

修改 对于没有功能的相同程序:

int candidate;
int perfectNumbers;

for(candidate = 1, perfectNumbers = 0; perfectNumbers < 150; candidate++) {

  [... here your algorithm to compute the sum of the divisors of "candidate" ...]

  if (candidate*2 == sum_of_divisors) {
    printf("Number %d is perfect\n", candidate);
    perfectNumbers++;
  }
}

EDIT2:只是关于完美数字的说明

如下面的评论部分所述,完美的数字是非常罕见的,截至2014年,其中只有48个已知。序列(A000396)也增长得非常快:使用64位整数你将是能够计算出最多8个完美数字(恰好是2,305,843,008,139,952,128)。在这种情况下,变量candidate将环绕并从头开始“查找”“新”完美数字(直到找到它们中的150个:实际上在64位整数中只有8个可查找的19个重复)。请注意,如果您将candidate声明为0,则您的算法不得仅限于0等于candidate或负数(仅限于unsigned int)。

答案 1 :(得分:0)

我正在解释这个问题意味着生成150以下可能是完美数字的所有数字。

因此,如果您的程序用于计算完美数字,则会一直计算它们,直到起始数字为>= 150

希望这是有道理的。

答案 2 :(得分:0)

嗯,这是我的解决方案..

首先,你必须采取一种可靠的方法来获得除数。
这是我为此所做的一项功能:

size_t
getdivisors(num, divisors)
    long long num;
    long long *divisors;
{
    size_t divs = 0;
    for(long long i = num; i > 0; --i)
        if (num%i == 0)
            divisors[divs++] = i;
    return divs;
}

其次,您需要检查数字的除数是否与完全数字的除数属性相匹配(它们的总和是数字的一半)。
这是第二个功能:

bool
isperfect(num)
    long long num;
{
    long long divisors[num/2+1];
    size_t divs = getdivisors(num, divisors);
    if (divs == 0)
        return false;
    long long n = 0;
    for(int i = 1; i < divs; ++i)
        n += divisors[i];
    return (n == num);
}

现在,从您的问题来看,我认为您需要打印所有小于150的完美数字,对吧? 见:

int
main(argc, argv)
    int argc;
    char ** argv;
{
    for(int i = 1; i < 150; ++i)
        if (isperfect(i))
            printf("%d is perfect.\n", i);
    return 0;
}

我希望能回答你的问题..