簡體   English   中英

素數查找程序的效率(c++)

[英]Efficiency of a prime number finding program(c++)

我想知道我制作的這段代碼是否效率低下,或者是否有更快的方法來查找素數。

#include <stdio.h>

int main(void)
{
    int count;

    for(int i=3; i<1000; i+=2){//search number in range of 3~999
        count=0;//init count
        for(int j=3; j*j<=i; j+=2){
            if(count==1){//if i has aliquot already, break the loop
                break;
            }
            if(i%j==0){
                count=1;//if i has aliquot, change count to 1
            }
        }
        if(count==0){
            printf("%d ", i);//if there are no aliquot, print i
        }
    }

    return 0;
}

似乎您正在使用試驗除法,這需要O (√ n ) 時間來確定單個數字的素數,因此在查找范圍內的所有素數時效率低下。 要有效地查找范圍內的所有素數,請考慮使用Eratosthenes 篩(時間復雜度為O ( n log n loglog n ))或歐拉篩(時間復雜度為O ( n ))。 以下是這兩種算法的簡單實現。

埃拉托色尼篩的實施

bool isPrime[N + 5];

void eratosthenes(int n) {
    for (int i = 2; i <= n; ++i) {
        isPrime[i] = true;
    }
    isPrime[1] = false;
    for (int i = 2; i * i <= n; ++i) {
        if (isPrime[i]) {
            for (int j = i * i; j <= n; j += i) {
                isPrime[j] = false;
            }
        }
    }
}

歐拉篩的實現

bool isPrime[N + 5];
std::vector<int> primes;

void euler(int n) {
    for (int i = 2; i <= n; ++i) {
        isPrime[i] = true;
    }
    isPrime[1] = false;
    for (int i = 2; i <= n; ++i) {
        if (isPrime[i]) primes.push_back(i);
        for (size_t j = 0; j < primes.size() && i * primes[j] <= n; ++j) {
            isPrime[i * primes[j]] = false;
            if (i % primes[j] == 0) break;
        }
    }
}

Eratosthenes Sieve 很酷,但已棄用? 為什么不使用我的 Prime 課程? 它有一個增量方法,不使用除法。 素數類通過其與較低素數的全等來描述一個數字。 增加一個素數是為了增加所有同余,如果整數是素數,則創建一個新同余(所有同余-模_-不同於0)。

#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>

class Prime {
public :
  Prime () : n_ (2), modulos_ (std::vector<std::pair<int, int> > ())
  {
    if (!modulos_.capacity ()) modulos_.reserve (100000000);
    std::pair<int, int> p (2, 0);
    modulos_.push_back (p);
  }
  ~Prime () {}
  Prime (const Prime& i) : n_ (i.n_), modulos_ (i.modulos_)
   {}
  bool operator == (const Prime& n) const {
    return (n_ == n.n_);
  }
  bool operator != (const Prime& n) const {
    return !operator == (n);
  }
  Prime& operator = (const Prime& i) {
    n_ = i.n_,
    modulos_ = i.modulos_;
    return *this;
  }
  void write (std::ostream& os) const {
    os << n_;
  }
  void operator ++ () {
    int prime (1);
    do {
      ++n_;
      prime = 1;
      std::for_each (modulos_.begin (), modulos_.end (), [&prime] (std::pair<int, int>& p) {
        ++p.second;
        if (p.first == p.second) {
          p.second = 0;
          prime  = 0;
        }
      });
    }
    while (!prime);
    std::pair<int, int> p (n_, 0);
    modulos_.push_back (p);
  }
  bool operator < (const int& s) const {
    return n_ < s;
  }
private :
  int n_;
  std::vector<std::pair<int, int> > modulos_; 
};

用法 :

int main (int, char**) {
  Prime p;
  do {
    p.write (std::cout);
    std::cout << std::endl;
    ++p;
  }
  while (p < 20);
}

結果:2 3 5 7 11 13 17 19

對於高達 1000 的素數,一種有效的方法是

cout << "2  3   5   7   11  13  17  19  23
29  31  37  41  43  47  53  59  61  67
71  73  79  83  89  97  101 103 107 109
113 127 131 137 139 149 151 157 163 167
173 179 181 191 193 197 199 211 223 227
229 233 239 241 251 257 263 269 271 277
281 283 293 307 311 313 317 331 337 347
349 353 359 367 373 379 383 389 397 401
409 419 421 431 433 439 443 449 457 461
463 467 479 487 491 499 503 509 521 523
541 547 557 563 569 571 577 587 593 599
601 607 613 617 619 631 641 643 647 653
659 661 673 677 683 691 701 709 719 727
733 739 743 751 757 761 769 773 787 797
809 811 821 823 827 829 839 853 857 859
863 877 881 883 887 907 911 919 929 937
941 947 953 967 971 977 983 991 997" << endl;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM