Java - simple program (finding cousins) - does not run

Asked

Viewed 3,766 times

2

I’m starting to learn java, I’m using the Java book to Beguinners Guide and this little problem appeared to find the primes of 1 - 100 and print on the screen. I made the following code.

class AllPrime {
    public static void main(String args[]) {
        int i;
        int counter = 0;
        int k;

        for(i = 1; 1 <= 100; i++)
        {
            for(k = 1; k <= i; k++)
            {
                if( (i % k) == 0)
                    ++counter;  
            }
            if( counter == 2 )
                System.out.println("The number: " + i + "is prime");
        }
    }
}

He hasn’t printed anything on the screen. I’ve read and reread this code and I can’t understand what’s wrong. He just doesn’t run.

  • Just remembering that a cousin only divides by himself and one, so the counter == 2

  • 1

    Try to put ++ on the right side of the contain variable

  • 1

    Need to reset to counter variable after if(counter == 2)

5 answers

6

You made some silly little mistakes.

  • Your big mistake is that you don’t do the counter go back to zero after iterating a number on i. Because of this, after deciding that 1 is not prime, he will never be able to decide which number is prime, since counter never diminishes.

  • Another small problem was the stopping condition of the for that was 1 <= 100 instead of i <= 100.

  • Finally, you can declare the variables i and k within itself for, don’t need to declare first.

  • One more space to add before the "is prime".

So, here’s your corrected code.

public class Main {
    public static void main(String args[]) {
        for (int i = 1; i <= 100; i++) {
            int counter = 0;
            for (int k = 1; k <= i; k++) {
                if (i % k == 0) ++counter;
            }
            if (counter == 2) {
                System.out.println("The number: " + i + " is prime");
            }
        }
    }
}

It’s also possible to optimize your code a little bit more, because you don’t have to ever test whether the number is divisible by 1 or by itself, because it always will be. This way, you no longer need to count the divisors, because as soon as you find a divisor you already know that the number is composed and you do not need to waste time testing the other numbers, being able to use the continue to proceed to the next iteration. This also eliminates the need for the variable counter. This way, your code looks like this:

public class Main {
    public static void main(String args[]) {
        out: for (int i = 1; i <= 100; i++) {
            for (int k = 2; k < i; k++) {
                if (i % k == 0) continue out;
            }
            System.out.println("The number: " + i + " is prime");
        }
    }
}

You can optimize further if you check that if the number is composed, then at least one of the divisors is less than or equal to square root of the number. So if you even get to the square root, you don’t find any divisor, it’s because the number is prime. Soon:

public class Main {
    public static void main(String args[]) {
        out: for (int i = 1; i <= 100; i++) {
            for (int k = 2; k <= Math.sqrt(i); k++) {
                if (i % k == 0) continue out;
            }
            System.out.println("The number: " + i + " is prime");
        }
    }
}

There are other possible mathematical tricks, in particular to avoid testing k which are compounds and also to compute the whole square root which is faster than the square floating point root. Other properties of primes and compounds can be used to reduce computational effort. However, these more aggressive optimizations would no longer be simple, and you probably want an algorithm that is quite simple, especially since you’re only testing the primes up to the number 100.

  • To optimize even more from to use for (int k = 2; k < sqrt(i); k++)

  • @Rcoster is right. Thank you very much. Reply edited..

3

The error is in the fact that you are not restarting the variable value counter for each i.

Behold:

  • The code starts with counter == 0.
  • When i == 1 and k == 1, i % k == 0. Soon, counter++ (counter == 1).
  • k is incremented, and exits the for.
  • When i == 2 and k == 1, i % k == 0. Soon, counter++ (counter == 2).
  • When i == 2 and k == 2, i % k == 0. Soon, counter++ (counter == 3).
  • k is incremented, and exits the for.

Notice that counter > 2 (counter == 3). By induction, the message will never be printed, since counter will only grow and already exceeded the expected value for message printing.

Restarting the value of counter in each iteration on i solves the problem:

class AllPrime {
    public static void main(String args[]) {
        int i;
        int k;

        for(i = 1; i <= 100; i++)
        {
            int counter = 0;
            for(k = 1; k <= i; k++)
            {
                if( (i % k) == 0)
                    ++counter;  
            }
            if( counter == 2 )
                System.out.println("The number: " + i + "is prime");
        }
    }
}

1

Complementing the previous answers, by the way, are already more than complete, I would like to leave an example where you have the possibility to make your code a little more flexible, where you yourself can determine the range at which you want to check all prime numbers, and provide you with one more way to see other perspectives on this problem.

import java.io.*;

public class AllPrime {
    public static void main(String args[]) throws IOException {

        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));

        int minimo;
        int maximo;

        System.out.println("****************************");
        System.out.println("Digite um intervalo: ");
        System.out.println("****************************");

        System.out.println("\nMinimo: ");
        minimo = Integer.parseInt(input.readLine());

        System.out.println("\nMaximo: ");
        maximo = Integer.parseInt(input.readLine());

        for (int i = minimo; i <= maximo; i++)
            if (isPrime(i)) imprimir(i);

    }

    public static boolean isPrime(int number) {
        int count = 2;

        for (int i = 2; i < number; i++) {
           if (number % i == 0) {
               count++;
           }
        }
        return count == 2;
    }

    public static void imprimir (int number) {
        System.out.println("The number: " + number + " is prime");
    }

}

1

You could do so by making a Static isPrime method, so that your code becomes simpler, organized and readable:

public class Main {

    public static void main(String args[]) {

        for (int i = 1; i <= 100; i++) {
           if (isPrime(i)) {
               System.out.println("The number: " + i + " is prime");
           }

        }

    }

    public static boolean isPrime(int x) {

       int count = 2;

       for (int i = 2; i < x; i++) {
          if (x % i == 0) {
              count++;
          }
       }

       return count == 2;

    }

}

0

System.out.println("Digite um numero:");
    int numero = scan.nextInt();

    int diferença = 0;

    for (int i = 1; i < numero; i++) {

        if (numero % i == 0) {
            diferença ++;
        }
    }

    if (diferença == 1) {
        System.out.println(numero +  " É Primo");
    }else {
        System.out.println(numero + " Não é primo");
    }
}
  • Answers, code only, without any explanation do not fit the Stackoverflow goal

Browser other questions tagged

You are not signed in. Login or sign up in order to post.