2011-11-02 93 views
2

可能重複:
Which is the fastest algorithm to find prime numbers?打印素數小於100

有沒有什麼辦法,使這更優化..

#include <vector> 
    int main() 
    { 
     std::vector<int> primes; 
     primes.push_back(2); 
     for(int i=3; i < 100; i++) 
     { 
      bool prime=true; 
      for(int j=0;j<primes.size() && primes[j]*primes[j] <= i;j++) 
      { 
       if(i % primes[j] == 0) 
       { 
        prime=false; 
        break; 
       } 
      } 
      if(prime) 
      { 
       primes.push_back(i); 
       cout << i << " "; 
      } 
     } 

     return 0; 
    } 
+2

你可以你的循環i ++在部分變爲I + = 2,因爲我們知道所有的連號都不會是首要反正 – Akron

+0

你需要添加作業標籤? –

+0

已經有很多關於此主題的SO問題。 – mydogisbox

回答

4

Sieve of Eratosthenes是一個偉大的算法用於產生一定數量的素數(這不是你的標題所指出的,b你的代碼暗示了什麼)。

+0

我不認爲Sieve算法在[1..100]內的數字的情況下比nave算法效果更好 –

+0

@SaeedAmiri任何你不認爲這個的原因? –

+0

@PaŭloEbermann,因爲在這個範圍內有很多可以分割爲2,3,5,7的數字,你會多次檢查它們,但是通過nave算法,你可以跳過這種類型的檢查,因爲只有3,5個, 7應該在nave算法中檢查,實際上最多隻有150個檢查,性能問題並不多,但在篩選算法中,我不知道應該有多少檢查,但應該超過150個,這只是猜測計算它並不困難。 –

1

是的,將i++更改爲i+=2,它的工作速度會提高一倍。

+0

不,它不會......只是微觀優化 –

+0

如果你只測試一半的數字,爲什麼它不會讓它快一倍? –

+0

,因爲您是針對第一個素數進行測試,即2,立即退出循環。 –

11
int main(int argc, char *argv[]) { 
    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 "; 
} 

:-)

更嚴重的是,你能避免緩存primes[j] * primes[j]反覆平方素數,節省乘法。

+0

101,你忘了! –

+0

+1:給定範圍的一個很好的答案。 –

+0

哈哈,我喜歡這個迴應。這是真正的最快的方式輸出所有素數低於100 – Akron

2
  1. 不做primes[j]*primes[j] <= i只是檢查primes[j] <= 7
  2. 使用i+=2
+0

考慮到'primes [3] == 7',寫'j <= 3'更簡單。 (primes [j] <11'會更明顯)。 – MSalters

1

是。正如Marion所建議的那樣,您可以使用Sieve of Eratosthenes,但您應該瞭解詳細信息。你寫的代碼看起來像篩子,但事實並非如此。它被稱爲審判分裂,它有不同於篩子的algorithmic complexity

篩子執行每個素數p需要Theta(n/p)時間的合格。這導致總複雜度爲O(n log log n)。 IIRC證明有點複雜,涉及prime number theorem

您的算法對每個素數p執行pi(sqrt(p))除法,對於非素數執行較小數目的除法。 (其中piprime-counting function)。不幸的是,我無法想出完全的複雜性。

簡而言之,您應該更改代碼以使用數組並標記所有非素數。 This article解決了函數式編程語言中的相同主題。

+0

是的。我顯然沒有想到它通過。 –

1

是的,Eratosthenes篩是最好​​的選擇(如果你需要100個以上的號碼this是最好的實施)。這是我的實現:

#include <vector> 
#include <iostream> 
#include <cmath> 
using namespace std; 

vector<int> sieve(int n){ 
    vector<bool> prime(n+1,true); 
    vector<int> res; 
    prime[0]=prime[1]=false; 
    int m = (int)sqrt(n); 
    for(int i=2; i<=m; i++){ 
     if(prime[i]) 
      for(int k=i*i; k<=n; k+=i) 
       prime[k]=false; 
    } 
    for(int i=0; i<n ;i++) 
     if(prime[i]) 
      res.push_back(i); 
    return res; 
} 

int main(){ 
    vector<int> primes = sieve(100); 
    for(int i=0; i<primes.size() ;i++){ 
     if(i) cout<<", "; 
     if(primes[i]) cout<<i; 
    } 
    cout<<endl; 
} 
+0

一個有趣的問題是,使用'vector '是否比使用'vector '要快(0和1爲false和true)。 'vector '當然需要額外的努力才能讀取或寫入任何單個值,但'vector '會佔用8倍以上的內存,減少了局部性,並導致更多的緩存未命中。 –

+0

在C++布爾和字符中使用8位,但布爾不使用所有這些。 – vudduu

+0

在C++中,「bool」或「c​​har」的大小是實現定義的。我知道今天的機器,其中'char'是8,9或32位,'bool'可以是單個'char',或者更多---肯定有系統,它的大小與int '(4或6個字節,在兩個平臺上我知道這是這種情況)。這裏沒有一個是相關的,因爲'std :: vector '專門用於每個布爾值只使用1位。我的評論從哪裏來。 –