2017-06-07 5 views
1

Quelqu'un peut-il s'il vous plaît me dire comment cela fonctionne dans O (n).Ce tamis est-il vraiment O (n)?

http://www.geeksforgeeks.org/sieve-eratosthenes-0n-time-complexity/

void manipulated_seive(int N) 
{ 
    // 0 and 1 are not prime 
    isprime[0] = isprime[1] = false ; 

    // Fill rest of the entries 
    for (long long int i=2; i<N ; i++) 
    { 
     // If isPrime[i] == True then i is 
     // prime number 
     if (isprime[i]) 
     { 
      // put i into prime[] vector 
      prime.push_back(i); 

      // A prime number is its own smallest 
      // prime factor 
      SPF[i] = i; 
     } 

     // Remove all multiples of i*prime[j] which are 
     // not prime by making isPrime[i*prime[j]] = false 
     // and put smallest prime factor of i*Prime[j] as prime[j] 
     // [ for exp :let i = 5 , j = 0 , prime[j] = 2 [ i*prime[j] = 10 ] 
     // so smallest prime factor of '10' is '2' that is prime[j] ] 
     // this loop run only one time for number which are not prime 
     for (long long int j=0; 
      j < (int)prime.size() && 
      i*prime[j] < N && prime[j] <= SPF[i]; 
      j++) 
     { 
      isprime[i*prime[j]]=false; 

      // put smallest prime factor of i*prime[j] 
      SPF[i*prime[j]] = prime[j] ; 
     } 
    } 
} 

Je pense que la boucle extérieure sera capable de O (n) du temps et de boucle interne se déroulera O (nombre de nombres premiers inférieur à N) dans le cas où des nombres premiers et O (1) dans le cas où de composite. Mais dans l'ensemble, il doit s'agir de O (n) * O (nombre de nombres premiers inférieur à n). Est-ce que je manque quelque chose?

Merci d'avance.

+0

Je pense qu'il est malhonnête de l'appeler 'O (N)'. Les constantes sur la multiplication et le stockage des nombres entiers sont pires que sur le trépan bit avec le tamis habituel. Au moment où le facteur 'log (log (N))' peut être important, il importera plutôt que la multiplication d'entiers de taille arbitraire soit loin du temps constant, et que vos constantes soient * encore * plus mauvaises. – btilly

+2

des indirections et des multiplications sans fin, des tableaux indexés par 'long long int', algorithme intrinsèquement non segmentable ... c'est garanti pour fonctionner de façon abyssale. Dès que N aura dépassé la taille de votre cache, il ralentira énormément, donc vous testeriez quoi, 10000 nombres premiers au maximum, si cela? peu probable que les multiplications bigint auront une chance d'entrer en jeu (@btilly). c'est [Gries & Misra] (https://www.cs.utexas.edu/users/misra/scannedPdf.dir/linearSieve.pdf), BTW. - La clé de l'efficacité de SoE est sa prétendue redondance. toute tentative de le supprimer entraîne trop de frais généraux. –

Répondre

2

L'idée clé est que chaque entier compris entre 2 et n est rencontré exactement une fois dans le calcul SPF, donc le nombre total d'itérations de la boucle la plus interne est O (n).

La boucle la plus interne remplit la matrice SPF qui indique le plus petit facteur premier, pour chaque entier compris entre 2 et n.

En effet, pour calculer la matrice SPF, chaque entier k entre 2 et n est représenté comme k = i*prime[j], où prime[j] est un nombre premier en dessous de tous les facteurs premiers de i (ce qui est assuré par la condition prime[j] <= SPF[i] ce qui casserait la boucle autrement). Cela signifie que prime[j] est le plus petit facteur premier de k. Mais cette représentation est unique pour chaque k (le même k ne sera pas rencontré une nouvelle fois, comme un autre k = i2 * prime[j2] factorisation, parce que si prime[j2] n'est pas égal à prime[j] alors l'un d'entre eux ne serait pas le plus petit facteur premier de k). Ainsi, chaque numéro k entre 2 et n apparaît exactement une fois comme le produit i*prime[j], calculé dans la boucle la plus interne.

+1

Merci, je l'ai maintenant. – rittik