1

Hello this is my first time asking a question here, I read the guidelines and I did look for an answer and did not find one so I hope my question is within the guidelines. Anyway I am stuck on a simple Java exercise where I have to output the first N perfect numbers (In number theory, a perfect number is a positive integer that is equal to the sum of its proper positive divisors, that is, the sum of its positive divisors excluding the number itself (also known as its aliquot sum).) So I did this

import java.util.Scanner;

public static void main(String[] args) {

    Scanner in = new Scanner(System.in);

    int cont = 0;
    int num = 1;
    int soma = 0;
    System.out.println("Quantos números perfeitos?");
    int n = in.nextInt();

    while (cont < n) {
        for (int i = 1; i <= num / 2; i++) {
            if (num % i == 0) {
                soma = soma + i;
            }
        }

        if (num == soma) {
            System.out.println(num + " é perfeito.");
            cont++;
        }
        num++;

    }
}

It gets stuck in an infinite loop and i can't figure out why. Anyway if someone can help me I'd really appreciate it and if my question has been answered or if it's just a stupid question sorry, as I said it is my first time asking. Thank you.

Pritam Banerjee
  • 17,953
  • 10
  • 93
  • 108
  • 1
    Welcome to StackOverflow. If you have an Integrated Development Environment, I'd suggest that you put breakpoints at several lines, especially soma = soma + i and if (num == soma). (If you don't have an IDE, please System.out.println some important variables.) – rajah9 Nov 21 '16 at 22:15
  • Probably because `cont++` is only incremented when it is a perfect number. First non-perfect number will get stuck in the loop. I think the while loop condition should be `while (num < n)`. – AntonH Nov 21 '16 at 22:16
  • Just general advice, rather than an answer, and this might be obviously apparent to you, but it is likely an issue that the for-loop is never producing a number where `soma == num`. As such, `cont++` is never being executed, and thus, `cont < n` is always true. There is likely a fundamental flaw in the implementation of searching for perfect numbers. Nonetheless, when it is infinitely looping, are you ever seeing the output from `System.out.println(num + " é perfeito.");` executing? If so, then my suggestion is wrong. Also, welcome to StackOverflow and thanks for reading the guidelines ;-) – Spencer D Nov 21 '16 at 22:17

1 Answers1

6

Your code looks good--the only thing you're forgetting to do is reset the value of soma every time in the while loop. In your current code, soma is the sum of the proper factors of all the numbers you looped through so far, which is not what you want.

Here's the code you would need:

Scanner in = new Scanner(System.in);

int cont = 0;
int num = 1;
int soma;
System.out.println("Quantos números perfeitos?");
int n = in.nextInt();

while (cont < n) {
    soma = 0; //Don't forget this line

    for (int i = 1; i <= num / 2; i++) {
        if (num % i == 0) {
            soma = soma + i;
        }
    }

    if (num == soma) {
        System.out.println(num + " é perfeito.");
        cont++;
    }

    num++;
}
416E64726577
  • 2,214
  • 2
  • 23
  • 47
  • Have you actually run that to make sure it fixes the infinite loop? I think you'll find there are other bugs (what happens if num != soma) – John3136 Nov 21 '16 at 22:20
  • 2
    Yes, I've tested it, and it seems to work. Output for n=3: `6 é perfeito. 28 é perfeito. 496 é perfeito.` – 416E64726577 Nov 21 '16 at 22:21
  • I added that and ran code, and it quickly finds the first 4 perfect number correctly. Finding the 5th one ([33550336](https://en.wikipedia.org/wiki/List_of_perfect_numbers)) will take a very long time using this algorithm. – Andreas Nov 21 '16 at 22:21
  • @John3136, if `num != soma`, then 416E6...'s answer resets `soma` and tries the next number to see if it is perfect. That is not a bug, as far as I can tell from the OP's question. – Spencer D Nov 21 '16 at 22:21
  • I missed the `num++` at the end of the loop. now I can see that stuff does actually change in the loop I'm happy ;-) – John3136 Nov 21 '16 at 22:25
  • 1
    Thank you for everyones help, if anyone has any suggestions on how to improve it I'd be very glad to see it because I can't really think of anything besides starting num at 2 and incrementing it by 2 since a perfect number must be even, I've noticed that all perfect numbers either finish in 6 or 8 so maybe something could be done with that. The 5th perfect number will take a ridiculous amount of time. For curiosity sake I will post both run times for incrementing num by 1 and by 2. Really surprised at how fast I got my answer and will definitely be asking again in the future, thank you ! – Danny Gomes Nov 22 '16 at 02:49
  • 1
    @DannyGomes - an interesting fact is that all known even perfect numbers are of the form 2^(p-1)*(2^p-1), where p is a prime. (https://en.wikipedia.org/wiki/List_of_perfect_numbers) – 416E64726577 Nov 22 '16 at 03:02