Générer des nombres premiers en Java

Générer des nombres premiers en Java

1. introduction

Dans ce tutoriel, nous allons montrer différentes manières de générer des nombres premiers en utilisant Java.

Si vous cherchez à vérifier si un nombre est premier, voicia quick guide pour savoir comment procéder.

2. Nombres premiers

Commençons par la définition de base. A prime number is a natural number greater than one that has no positive divisors other than one and itself.

Par exemple, 7 est premier car 1 et 7 sont ses seuls facteurs entiers positifs, alors que 12 ne l’est pas parce qu’il possède les diviseurs 3 et 2 en plus de 1, 4 et 6.

3. Générer des nombres premiers

Dans cette section, nous verrons comment nous pouvons générer efficacement des nombres premiers inférieurs à une valeur donnée.

3.1. Java 7 et avant - Brute Force

public static List primeNumbersBruteForce(int n) {
    List primeNumbers = new LinkedList<>();
    for (int i = 2; i <= n; i++) {
        if (isPrimeBruteForce(i)) {
            primeNumbers.add(i);
        }
    }
    return primeNumbers;
}
public static boolean isPrimeBruteForce(int number) {
    for (int i = 2; i < number; i++) {
        if (number % i == 0) {
            return false;
        }
    }
    return true;
}

Comme vous pouvez le voir,primeNumbersBruteForce itère sur les nombres de 2 àn et appelle simplement la méthodeisPrimeBruteForce() pour vérifier si un nombre est premier ou non.

La méthode vérifie la divisibilité de chaque nombre par les nombres dans une plage de 2 ànumber-1.

If at any point we encounter a number that is divisible, we return false. À la fin, lorsque nous constatons que ce nombre n'est divisible par aucun de ses nombres précédents, nous retournons true indiquant que c'est un nombre premier.

3.2. Efficacité et optimisation

L'algorithme précédent n'est pas linéaire et a la complexité temporelle de O (n ^ 2). L’algorithme n’est pas non plus efficace et il est clairement possible d’améliorer.

Examinons la condition dans la méthodeisPrimeBruteForce().

Lorsqu'un nombre n'est pas un nombre premier, ce nombre peut être factorisé en deux facteurs à savoira etb i.e. number = a * b. If both a and b were greater than the square root of n, a*b would be greater than n.

Donc, au moins un de ces facteurs doit être inférieur ou égal à la racine carrée d'un nombre et pour vérifier si un nombre est premier, il suffit de rechercher des facteurs inférieurs ou égaux à la racine carrée du nombre vérifié.

Les nombres premiers ne peuvent jamais être un nombre pair car les nombres pairs sont tous divisibles par 2.

De plus, les nombres premiers ne peuvent jamais être un nombre pair car les nombres pairs sont tous divisibles par 2.

En gardant à l'esprit les idées ci-dessus, améliorons l'algorithme:

public static List primeNumbersBruteForce(int n) {
    List primeNumbers = new LinkedList<>();
    if (n >= 2) {
        primeNumbers.add(2);
    }
    for (int i = 3; i <= n; i += 2) {
        if (isPrimeBruteForce(i)) {
            primeNumbers.add(i);
        }
    }
    return primeNumbers;
}
private static boolean isPrimeBruteForce(int number) {
    for (int i = 2; i*i < number; i++) {
        if (number % i == 0) {
            return false;
        }
    }
    return true;
}

3.3. Utiliser Java 8

Voyons comment nous pouvons réécrire la solution précédente en utilisant les idiomes Java 8:

public static List primeNumbersTill(int n) {
    return IntStream.rangeClosed(2, n)
      .filter(x -> isPrime(x)).boxed()
      .collect(Collectors.toList());
}
private static boolean isPrime(int number) {
    return IntStream.rangeClosed(2, (int) (Math.sqrt(number)))
      .filter(n -> (n & 0X1) != 0)
      .allMatch(n -> x % n != 0);
}

3.4. Utilisation du tamis d'Eratosthène

Il existe une autre méthode efficace qui pourrait nous aider à générer efficacement des nombres premiers, et elle s’appelle Sieve Of Eratosthenes. Son efficacité temporelle est O (n logn).

Jetons un coup d'œil aux étapes de cet algorithme:

  1. Créer une liste d'entiers consécutifs de 2 àn: (2, 3, 4,…, n)

  2. Initialement, soitp égal à 2, le premier nombre premier

  3. À partir dep, comptez par incréments dep et marquez chacun de ces nombres supérieurs àp lui-même dans la liste. Ces nombres seront 2p, 3p, 4p, etc. noter que certains d’entre eux ont peut-être déjà été marqués

  4. Trouvez le premier nombre supérieur àp dans la liste qui n'est pas marqué. S'il n'y en avait pas, arrêtez-vous. Sinon, laissezp maintenant égaler ce nombre (qui est le prochain premier), et répétez à partir de l'étape 3

À la fin de l'algorithme, tous les nombres de la liste qui ne sont pas marqués sont des nombres premiers.

Voici à quoi ressemble le code:

public static List sieveOfEratosthenes(int n) {
    boolean prime[] = new boolean[n + 1];
    Arrays.fill(prime, true);
    for (int p = 2; p * p <= n; p++) {
        if (prime[p]) {
            for (int i = p * 2; i <= n; i += p) {
                prime[i] = false;
            }
        }
    }
    List primeNumbers = new LinkedList<>();
    for (int i = 2; i <= n; i++) {
        if (prime[i]) {
            primeNumbers.add(i);
        }
    }
    return primeNumbers;
}

3.5. Exemple de travail de tamis d'ératosthène

Voyons comment cela fonctionne pour n = 30.

image

Considérons l'image ci-dessus, voici les passes effectuées par l'algorithme:

  1. La boucle commence par 2, nous laissons donc 2 non marqués et marquons tous les diviseurs de 2. Il est marqué dans l'image avec la couleur rouge

  2. La boucle passe à 3, nous laissons donc 3 non marqués et marquons tous les diviseurs de 3 non marqués. Il est marqué dans l'image avec la couleur verte

  3. La boucle passe à 4, elle est déjà marquée, alors nous continuons

  4. La boucle passe à 5, nous laissons donc 5 non marquées et marquons tous les diviseurs de 5 non marqués. Il est marqué dans l'image avec la couleur violette

  5. Nous continuons les étapes ci-dessus jusqu'à ce que la boucle soit atteinte égale à la racine carrée den

4. Conclusion

Dans ce didacticiel rapide, nous avons illustré différentes manières de générer des nombres premiers jusqu’à la valeur «N».

L'implémentation de ces exemples peut être trouvéeover on GitHub.