Question

Y at-il agréable de trouver l'algorithme le plus proche nombre premier à un numéro de real donné? Je ne dois effectuer des recherches dans les 100 premiers nombres premiers environ.

À l'heure actuelle, j'ai un tas de nombres premiers stockés dans un tableau et je vérifie la différence d'un numéro à la fois (O (n)?).

Était-ce utile?

La solution

Au lieu d'une liste triée des nombres premiers, compte tenu de la gamme relativement faible Ciblée, ont un tableau indexé par tous les nombres impairs dans la gamme (vous savez qu'il n'y a pas même les nombres premiers, sauf le cas particulier de 2) et contenant le plus proche premier . Trouver la solution devient O (1) temps-sage.

Je pense que le premier est vers 100 541. un tableau de 270 [small] ints est tout ce qui est nécessaire.

Cette approche est particulièrement valable, étant donné la forte densité relative des nombres premiers (en particulier par rapport à des nombres impairs), dans la plage inférieure à 1000. (Comme cela affecte la taille d'un arbre binaire)

Autres conseils

Si vous ne devez rechercher dans les 100 premiers nombres premiers ou, créez simplement une table triée de ces nombres premiers, et faire une recherche binaire. Cela soit vous rendre à un nombre premier, ou un endroit entre les deux, et vous vérifiez que ceux est plus proche.

Edit: Compte tenu de la distribution des nombres premiers dans cette gamme, vous pourriez probablement accélérer les choses (un petit peu) en utilisant une recherche d'interpolation - au lieu de toujours partir au milieu de la table, utilisez interpolation linéaire pour deviner un point de départ plus précis. Le 100 e nombre premier devrait être quelque part autour de 250 ou alors (à une supposition - je n'ai pas vérifié), donc si (par exemple) que vous vouliez le plus proche de 50, vous devriez commencer à environ 1 / 5ème de la voie dans le tableau au lieu de mi-chemin. Vous pouvez très bien traiter les nombres premiers en commençant à 1, donc diviser simplement le numéro que vous voulez le plus grand dans votre gamme pour obtenir une estimation au point de départ.

Les réponses à ce jour sont assez compliquées, compte tenu de la tâche à accomplir. Les cent premiers nombres premiers sont moins de 600 . Je voudrais créer un tableau de taille 600 et dans chaque la valeur du plus proche prime à ce numéro. Ensuite, étant donné un certain nombre de tester, j'arrondir à la fois de haut en bas à l'aide des fonctions de floor et ceil pour obtenir une ou deux réponses de candidats. Une simple comparaison avec les distances à ces chiffres vous donnera une réponse très rapide.

L'approche la plus simple serait de stocker les nombres premiers dans une liste triée et modifier votre algorithme pour faire une recherche binaire.

L'algorithme de recherche binaire standard retournerait nulle pour un échec, mais il devrait être tout droit vers l'avant de modifier à vos besoins.

L'algorithme le plus rapide? Créer une table de consultation avec p [100] = 541 éléments et retourne le résultat de floor (x), avec une logique spéciale de x sur [2,3]. Ce serait O (1).

Vous devez trier votre numéro dans le tableau, vous pouvez utiliser recherche binaire . Cet algorithme est O (log n) performance dans le pire des cas.

public static boolean p(int n){

    for(int i=3;i*i<=n;i+=2) {
        if(n%i==0)
            return false;
    }
    return n%2==0? false: true; }

public static void main(String args[]){
    String n="0";
    int x = Integer.parseInt(n);
    int z=x;
    int a=0;
    int i=1;
    while(!p(x)){

      a = i*(int)Math.pow(-1, i);
      i++;
      x+=a;
    }

    System.out.println( (int) Math.abs(x-z));}

ceci est pour n> = 2.

En python:

>>> def nearest_prime(n):
    incr = -1
    multiplier = -1
    count = 1
    while True:
        if prime(n):
            return n
        else:
            n = n + incr
            multiplier = multiplier * -1
            count = count + 1
            incr = multiplier * count

>>> nearest_prime(3)
3
>>> nearest_prime(4)
3
>>> nearest_prime(5)
5
>>> nearest_prime(6)
5
>>> nearest_prime(7)
7
>>> nearest_prime(8)
7
>>> nearest_prime(9)
7
>>> nearest_prime(10)
11
<?php
$N1Diff = null;
$N2Diff = null;

$n1 = null;
$n2 = null;

$number = 16;

function isPrime($x) {

    for ($i = 2; $i < $x; $i++) {
        if ($x % $i == 0) {
            return false;
        }
    }

    return true;
}


for ($j = $number; ; $j--) {

    if( isPrime($j) ){
       $N1Diff = abs($number - $j);
       $n1 = $j;
       break;
    }
}


for ($j = $number; ; $j++) {

    if( isPrime($j) ){
       $N2Diff = abs($number - $j);
       $n2 = $j;
       break;
    }

}

if($N1Diff < $N2Diff) {

    echo $n1;

} else if ($N1Diff2 < $N1Diff ){
    echo $n2;
}

Si vous voulez écrire un algorithme, une recherche Wikipedia pour m'a conduit à un autre article sur le Sieve de Eratosthène. L'algorithme semble un peu simple et je pense une fonction récursive conviendrait bien imo. (Je peux me tromper à ce sujet.)

Si la solution de tableau n'est pas une solution valable pour vous (il est le meilleur pour votre scénario), vous pouvez essayer le code ci-dessous. Après le cas « 2 ou 3 », il vérifiera chaque nombre impair loin de la valeur de départ jusqu'à ce qu'il trouve un nombre premier.

static int NearestPrime(double original)
{
    int above = (int)Math.Ceiling(original);
    int below = (int)Math.Floor(original);

    if (above <= 2)
    {
        return 2;
    }

    if (below == 2)
    {
        return (original - 2 < 0.5) ? 2 : 3;
    }

    if (below % 2 == 0) below -= 1;
    if (above % 2 == 0) above += 1;

    double diffBelow = double.MaxValue, diffAbove = double.MaxValue;

    for (; ; above += 2, below -= 2)
    {
        if (IsPrime(below))
        {
            diffBelow = original - below;
        }

        if (IsPrime(above))
        {
            diffAbove = above - original;
        }

        if (diffAbove != double.MaxValue || diffBelow != double.MaxValue)
        {
            break;
        }
    }

    //edit to your liking for midpoint cases (4.0, 6.0, 9.0, etc)
    return (int) (diffAbove < diffBelow ? above : below);
}

static bool IsPrime(int p)  //intentionally incomplete due to checks in NearestPrime
{
    for (int i = 3; i < Math.Sqrt(p); i += 2)
    {
        if (p % i == 0)
            return false;
    }

    return true;
}

table de correspondance avec la taille de 100 octets; (caractères non signés) nombre réel rond et utilisation table de consultation.

réponse- Simplest Chaque nombre premier peut être représenté sous la forme (6 * x-1 et 6 * X 1) (sauf 2 et 3). laissez nombre est N.divide avec 6. t = N / 6; maintenant a = (t-1) * 6 b = (t + 1) * 6 et vérifier que l'on est plus près de N.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top