題目:
求1到1億間的質數或素數
思路:
什麼是質數?
質數(prime number)又稱素數,有無限個。一個大於1的自然數,除了1和它本身外,不能被其他自然數(質數)整除,換句話說就是該數除了1和它本身以外不再有其他的因數;否則稱為合數。(來自百度百科)
方法1:
遍歷1到1億間的所有數,然後逐個判斷是否為質數;
如何判斷一個數為質數?根據質數的定義,判斷該數是否能被1和它本身之外的數整除,如果是,則不是質數,否則為質數;一般只需判斷是否能被2到sqrt(num)的所有數整數。
方法2:
上述方法時間複雜度較高,對於1億個數而言,不太實際。
其實當我們遍歷到某個數(如:n)的時候,所有n的倍數的數字均不為質數,後續我們無需對這個數再做判斷的操作,這樣可以減少很多不必要的計算;
而且,我們可以從逆向思維來考慮,出了各個n的倍數的數字之外,其他的就是質數,於是少了判斷是否為質數的過程。
現在需要做的就是將這些提前判斷為非質數的數字儲存起來,可以通過一個bool陣列,如果某個數字為非質數,則在對應下標的陣列位置做標誌,以供後續判斷。
時間複雜度:O(n),空間複雜度:O(n)
注意:
這裡處理的是一億個數字,因此需考慮機器的記憶體問題,32位機器的int表示範圍為0~2^32-1即4394967295,能表示一億,一億個int需要的記憶體為400M。
(下面的程式碼建立在記憶體足夠的情況下)
程式碼:
#include <iostream>
#include <vector>
using namespace std;
const unsigned int MAX_NUM=100;
void Prime(vector<bool> &numbers,vector<int> &primes){
for(unsigned int i=2;i<=MAX_NUM;i++){
if(numbers[i]==false){
primes.push_back(i);
// multiple of i
for(unsigned int j=i;j<=MAX_NUM;j+=i)
numbers[j]=true;
}
}
}
int main()
{
vector<bool> numbers(MAX_NUM,false);
vector<int> primes;
Prime(numbers,primes);
vector<int>::iterator it=primes.begin();
for(;it!=primes.end();it++){
cout<<*it<<endl;
}
return 0;
}