完美的数字,数组,验证和操作

时间:2012-12-02 14:14:50

标签: c arrays loops perfect-numbers

我正在尝试在C中编写一个代码,它允许在数组中最多输入10个元素(自然数),识别数组中的所有完美数字,并执行所有非完美数字的乘积。 / p>

  

Euclid证明2 ^ {p-1}(2 ^ p-1)是一个偶数完美的数,每当2 ^ p-1   是素数(Euclid,Prop.IX.36)。例如,前四个完美   数字由公式2 ^ {p-1}(2 ^ p-1)生成,其中p为素数   数量,如下:对于p = 2:2 ^ 1(2 ^ 2-1)= 6对于p = 3:2 ^ 2(2 ^ 3-1)=   对于p = 5:28 ^ 2(2 ^ 5-1)= 496,对于p = 7:2 ^ 6(2 ^ 7-1)= 8128。   (来源:维基百科)

当我编译程序时,我会重复三次或更高次数的完整数字声明。

e.g:

  

... t [10] = {1,1,1,1,1,1,1,1,1,6}

     

'6'是一个完美的数字。   '6'是一个完美的数字。   '6'是一个完美的数字。   ...

我也得到了一些奇怪的产品。

e.g:

  

... t [10] = {1,1,1,1,1,1,1,1,1,28}

     

'28'是一个完美的数字。   '28'是一个完美的数字。   '28'是一个完美的数字。   '28'是一个完美的数字。   '28'是一个完美的数字。   '28'是一个完美的数字。   '28'是一个完美的数字。   '28'是一个完美的数字。   '28'是一个完美的数字。   '28'是一个完美的数字。   '28'是一个完美的数字。   '28'是一个完美的数字。   '28'是一个完美的数字。   ...   非完美数字的乘积是-1677721600

我真的很新c,我似乎无法弄清楚我做错了什么,但我也不会给出一份讲义。我们非常感谢一些指导。

#include <stdio.h>
#define MAX_BOUND 9  /*Array's bound*/

main() {

int i, /*array index*/
    t[i],
    d, /*divider*/ 
    sum, /*result for perfect number validation*/
    product; /*product of all non-perfect number in array*/

i = 0;

printf("Enter your natural numbers. \n");

for (i = 0; i <= MAX_BOUND; i++) {
printf("Number %d : ", i + 1);
scanf( "%d", &t[i]);
}

i = 0;
product = 1;
for (i = 0; i <= MAX_BOUND; i++) {   
    d = 1;
    sum = 0;
    while(d < t[i]) {
        if(t[i]%d == 0)
        sum = sum + d;
        d++;

            if(sum == t[i])
            printf("%d is a perfect number. \n", t[i]);
            else
            product = product * t[i];
    }
}  
printf("The product of the non-perfect numbers is %d \n", product);
getch();
}

2 个答案:

答案 0 :(得分:2)

“奇怪的产品”(例如负面)是由integer overflow引起的。您的产品为int,使其更大,例如long long

您应该for使用i,而不是while。检查数字是否完美的代码应放在单独的函数bool isPerfect(int number)中。

您的意思是sum = 0,而不是somme = 0。声明t[i]也是错误的。

更正版本(使用gcc -std=c99 file.c编译):

#include <stdio.h>
#include <stdbool.h>
#define MAX 10

int t[MAX];

bool isPerfect(int number)
{
    int sum = 0;
    for (int d = 1; d < number; ++d) // optimization: you can iterate until sqrt(number)
    {
        if (number % d == 0)
        {
            sum += d;
        }
    }
    return sum == number;
}

int main()
{
    printf("Enter your natural numbers. \n");
    for (int i = 0; i < MAX; ++i)
    {
        printf("Number %d: ", i + 1);
        scanf("%d", &t[i]);
    }
    long long product = 1;
    for (int i = 0; i < MAX; ++i)
    {
        if (isPerfect(t[i]))
        {
            printf("%d is a perfect number. \n", t[i]);
        }
        else
        {
            product = product * t[i];
        }
    }
    printf("The product of the non-perfect numbers is %lld \n", product);
    return 0;
}

答案 1 :(得分:1)

在您对数组的声明中,您有未定义的行为,因为您使用了错误的大小:

main() {

    int i, 
        t[i],
        d, /*divider*/ 
        sum, 
        product;

    i = 0;

    printf("Enter your natural numbers. \n");

    while (i <= 9) {
        printf("Number %d : ", i + 1);
        scanf( "%d", &t[i]);
        i++;
    }

你可能想宣布

t[MAX_BOUND+1];

MAX_BOUND会出错,因为您使用了元素t[MAX_BOUND])。

在声明t时,i具有不确定的值(不一定是0)。

对于不确定的数组大小,访问t[i]会产生更多不确定的值(如果i >= sizeof t / sizeof t[0],则会再次出现未定义的行为。)

印刷部分,

        if(sum == t[i])
        printf("%d is a perfect number. \n", t[i]);
        else
        product = product * t[i];
在用于确定除数和的循环之后应该移动

。在循环内部,您将productt[i]乘以t[i] - 1次(如果其中一个中间总和等于t[i] - 2,则为t[i]){ {1}}并不完美,如果t[i]完美,则为t[i]/2-1次。此外,您打印t[i]次以获得完美数字,如果其中一个中间总和等于t[i]/2,则打印一次(我忽略了奇数完全数的理论可能性,如果有的话) ,它们对于t[i]来说太大了。

这样做会产生正确的输出。