web-dev-qa-db-fra.com

Test du nombre premier très simple - Je pense ne pas comprendre la boucle

Je pratique des examens antérieurs pour un examen de base en Java et j’ai du mal à faire en sorte que la boucle d’essai permette de vérifier si un nombre est premier. Je ne veux pas compliquer les choses en ajoutant des mesures d'efficacité pour les grands nombres, mais simplement quelque chose qui fonctionnerait au moins pour les nombres à 2 chiffres.

Pour le moment, il retourne toujours faux même si n IS est un nombre premier.

Je pense que mon problème est que je ne me trompe pas avec la boucle même et où placer le "retour vrai"; et "retourne faux;" ... je suis sûr que c'est une erreur fondamentale que je fais ...

public boolean isPrime(int n) {
    int i;
    for (i = 2; i <= n; i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

La raison pour laquelle je n'ai pas pu trouver d'aide ailleurs sur stackoverflow, c'est parce que des questions similaires demandaient une implémentation plus compliquée afin de disposer d'un moyen plus efficace de le faire.

13
BexLE

Votre boucle for a un petit problème. CA devrait etre: -

for (i = 2; i < n; i++)  // replace `i <= n` with `i < n`

Bien sûr, vous ne voulez pas vérifier le reste lorsque n est divisé par n. Il vous donnera toujours 1.

En fait, vous pouvez même réduire le nombre d'itérations en modifiant la condition en: - i <= n / 2. Étant donné que n ne peut pas être divisé par un nombre supérieur à n / 2, sauf lorsque nous considérons n, que nous n'avons pas à prendre en compte.

Ainsi, vous pouvez changer votre boucle for en: -

for (i = 2; i <= n / 2; i++)  
31
Rohit Jain

Vous pouvez vous arrêter beaucoup plus tôt et parcourir la boucle plus rapidement avec:

public boolean isPrime(long n) {
    // fast even test.
    if(n > 2 && (n & 1) == 0)
       return false;
    // only odd factors need to be tested up to n^0.5
    for(int i = 3; i * i <= n; i += 2)
        if (n % i == 0) 
            return false;
    return true;
}
31
Peter Lawrey

Vous devriez écrire i < n, car la dernière étape vous donnera true.

3
Zoltán Tamási

L'erreur est i <= n

for (i = 2; i<n; i++){
3
Gabriele Mariotti
public class PrimeNumberCheck {
  private static int maxNumberToCheck = 100;

  public PrimeNumberCheck() {
  }

    public static void main(String[] args) {
      PrimeNumberCheck primeNumberCheck = new PrimeNumberCheck();

      for(int ii=0;ii < maxNumberToCheck; ii++) {
        boolean isPrimeNumber = primeNumberCheck.isPrime(ii);

      System.out.println(ii + " is " + (isPrimeNumber == true ? "prime." : "not prime."));
    }
  }

  private boolean isPrime(int numberToCheck) {    
    boolean isPrime = true;

    if(numberToCheck < 2) {
      isPrime = false;
    }

    for(int ii=2;ii<numberToCheck;ii++) {
      if(numberToCheck%ii == 0) {
        isPrime = false;
        break;
      }
    }

    return isPrime;
  }
}
2
user2033388

Avec ce numéro de code divisible par 3, l’initialisation du code pour la boucle sera ignorée. 
Pour l’itération de la boucle, les multiples de 3 seront également ignorés.

private static boolean isPrime(int n) {

    if ((n > 2 && (n & 1) == 0) // check is it even
       || n <= 1  //check for -ve
       || (n > 3 && (n % 3 ==  0))) {  //check for 3 divisiable
            return false;
    }

    int maxLookup = (int) Math.sqrt(n);
    for (int i = 3; (i+2) <= maxLookup; i = i + 6) {
        if (n % (i+2) == 0 || n % (i+4) == 0) {
            return false;
        }
    }
    return true;
}
1
Kanagavelu Sugumar

L'un des moyens les plus rapides est de boucler jusqu'à la racine carrée de n.

  private static boolean isPrime(int n){
        int square = (int)Math.ceil((Math.sqrt(n)));//find the square root
        HashSet<Integer> nos = new HashSet<>(); 
        for(int i=1;i<=square;i++){
            if(n%i==0){
                if(n/i==i){
                    nos.add(i);
                }else{
                    nos.add(i);
                    int rem = n/i;
                    nos.add(rem);
                }
            }
        }
        return nos.size()==2;//if contains 1 and n then prime
    }
1
Ram Kumar

Vous pouvez également utiliser une propriété mathématique simple pour cela dans votre boucle for. 

Un nombre 'n' sera un nombre premier si et seulement s'il est divisible par lui-même ou par 1. 1 Si un nombre n'est pas un nombre premier, il aura deux facteurs: 

n = a * b

vous pouvez utiliser la boucle for pour vérifier jusqu'à sqrt du nombre 'n' au lieu d'aller jusqu'au 'n'. Comme dans si 'a' et 'b' sont tous les deux supérieurs au carré du nombre 'n', a * b serait supérieur à 'n'. Donc, au moins un des facteurs doit être inférieur ou égal à la racine carrée. 

donc votre boucle serait quelque chose comme ci-dessous: 

for(int i=2; i<=Math.sqrt(n); i++)

Ce faisant, vous réduiriez considérablement la complexité du code en termes de temps d'exécution ... Je pense que cela reviendrait à O (n/2). 

1
Nitesh Joshi

Le faire à la manière de Java 8 est plus gentil et plus propre

    private static boolean isPrimeA(final int number) {
        return IntStream
               .rangeClosed(2, number/2)
               .noneMatch(i -> number%i == 0);
    }
0
Sal

Vous vérifiez i<=n.Alors lorsque i==n, vous obtiendrez 0 seulement et il retournera false toujours. Essayez i<=(n/2).Pas besoin de vérifier jusqu'à i<n.

0
Renjith

Eh bien, la boucle for a un problème. Voici le code,

public static boolean checkPrimeNUmber(int number) 
{ 
   if(number <= 1) 
   { 
      return false; 
   } 
   for(int a = 2; a < Math.sqrt(number); a++) 
   { 
      if(number % a == 0) 
      { 
         return false; 
      } 
   } 
   return true;
}
0
Shiva

L'algorithme mentionné ci-dessus considère que 1 est premier, même s'il ne l'est pas. Voici donc la solution.

static boolean isPrime(int n) {
  int perfect_modulo = 0;
  boolean prime = false;

  for ( int i = 1; i <=  n; i++ ) {
    if ( n % i == 0 ) {
      perfect_modulo += 1;
    }
  }
  if ( perfect_modulo == 2 ) {
    prime = true;
  }

  return prime;
}
0
kxhitiz