web-dev-qa-db-fra.com

Trouver un nombre premier après un nombre donné

Comment trouver le plus petit nombre premier supérieur à un nombre donné? Par exemple, étant donné 4, j'ai besoin de 5; étant donné 7, j'ai besoin de 11.

J'aimerais connaître quelques idées sur les meilleurs algorithmes pour le faire. Une méthode à laquelle j'ai pensé était de générer des nombres premiers à travers le tamis d'Eratosthène, puis de trouver le nombre premier après le nombre donné.

33
avd

Certaines autres méthodes ont été suggérées et je pense qu’elles sont bonnes, mais cela dépend vraiment de la quantité de données que vous souhaitez stocker ou calculer. Par exemple, si vous recherchez le prochain nombre premier après un très grand nombre, l'utilisation du tamis d'Eratosthène risque de ne pas être si grande à cause du nombre de bits que vous auriez besoin de stocker. 

Vous pouvez également vérifier tous les nombres entiers impairs entre (et compris) 3 et sqrt (N) sur chaque nombre impair N supérieur au nombre entré jusqu'à ce que vous trouviez le nombre correct. Bien sûr, vous pouvez arrêter de vérifier si vous trouvez que c'est composite. 

Si vous voulez une méthode différente, je vous suggère alors d'utiliser le test de primalité Miller-Rabin sur tous les nombres impairs au-dessus du nombre entré (en supposant que l'entrée est> 1) jusqu'à ce qu'un nombre premier soit trouvé. Si vous suivez la liste, au bas de la page, des nombres a pour vérifier les plages données, vous pouvez réduire considérablement le nombre de as que vous devez vérifier. Bien sûr, vous pouvez vérifier au moins quelques-uns des plus petits nombres premiers (3,5,7,11 par exemple) avant de vérifier avec Miller-Rabin. 

6
Justin Peel

Source: Wikipedia

Le postulat de Bertrand (en réalité un théorème) stipule que si n> 3 est un entier, il existe toujours au moins un nombre premier p avec n <p <2n - 2. Une formulation plus faible mais plus élégante est: pour chaque n> 1 il y a toujours au moins un nombre premier p tel que n <p <2n.

Donc, si on me donne un nombre, disons n, je peux vérifier dans la plage (n, 2 * n) [intervalle ouvert à l'exclusion de n et 2 * n]

int GetNextPrime(int n)
{
    bool isPrime = false;
    for (int i = n; i < 2 * n; ++i)
    {
    // go with your regular prime checking routine
    // as soon as you find a prime, break this for loop
    }
}
24
Rajendra Uppal

Je l'ai fait avant.

Le seul ajout est le théorème de Bertrand tiré de La réponse de Rajendra .

Et le code readymade de topcoder .

#include<iostream>
using namespace std;

/* This function calculates (ab)%c */
int modulo(int a,int b,int c){
    long long x=1,y=a; // long long is taken to avoid overflow of intermediate results
    while(b > 0){
        if(b%2 == 1){
            x=(x*y)%c;
        }
        y = (y*y)%c; // squaring the base
        b /= 2;
    }
    return x%c;
}

/* this function calculates (a*b)%c taking into account that a*b might overflow */
long long mulmod(long long a,long long b,long long c){
    long long x = 0,y=a%c;
    while(b > 0){
        if(b%2 == 1){
            x = (x+y)%c;
        }
        y = (y*2)%c;
        b /= 2;
    }
    return x%c;
}

/* Miller-Rabin primality test, iteration signifies the accuracy of the test */
bool Miller(long long p,int iteration){
    if(p<2){
        return false;
    }
    if(p!=2 && p%2==0){
        return false;
    }
    long long s=p-1;
    while(s%2==0){
        s/=2;
    }
    for(int i=0;i<iteration;i++){
        long long a=Rand()%(p-1)+1,temp=s;
        long long mod=modulo(a,temp,p);
        while(temp!=p-1 && mod!=1 && mod!=p-1){
            mod=mulmod(mod,mod,p);
            temp *= 2;
        }
        if(mod!=p-1 && temp%2==0){
            return false;
        }
    }
    return true;
}

int main(int argc, char* argv[])
{

    int input = 1000;
    int i = 0;

    if(input%2==0)
        i = input+1;
    else i = input;

    for(;i<2*input;i+=2) // from Rajendra's answer
        if(Miller(i,20)) // 18-20 iterations are enough for most of the applications.
            break;
    cout<<i<<endl;

    return 0;
}
7
Pratik Deoghare

Je vois généralement deux façons de le faire. 

  • compter jusqu'à n et vérifier chaque nombre pour qu'il soit premier ou non
  • générer des nombres premiers et vérifier contre eux. (peut-être que vous le feriez auparavant, utilisez un tableau de nombres premiers existant, de sorte que vous n'ayez pas à calculer des trucs à chaque fois (tant que N est dans la plage de votre tableau précalculé) 

peut-être que cela aide aussi (remplacez simplement 2 par votre nombre donné et N par infini: D) trouver tous les nombres premiers compris entre 2 et N

1
samsam

J'aurais une grande table de recherche, puis chercherais le numéro et répondrais avec le suivant dans la séquence.

Fonctionne bien s’il existe une limite supérieure connue (sensible) à l’intervalle des nombres donnés.

0
Martin
private static int nextPrime(int num) {
        num++;
        for (int i = 2; i <num; i++) {
            if(num%i == 0) {
                num++;
                i=2;
            } else{
                continue;
            }
        }
        return num;
    }
0
ranafeb14