閒暇時寫了乙個找出小於某個數字的素數的程式。
最常見的方法是篩選法吧。原理大致如下:
若要求得16以內的所有素數,
1)在陣列中存放一下資料: 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
2)
先篩選掉是2的倍數: 2
3 4
5 6
7 8
9 10
11 12
13 14
15 16
同理,繼續篩選掉3的倍數.
當要篩選4的倍數的時候,由於4已經被篩選過了,所以4的倍數也必定篩選過了。因而跳過4,到5.剩下的步驟就類似了。
實際程式設計的時候,對乙個陣列進行操作。首先初始化陣列,令所有元素都為0.
const int c_size = 100;
int *data = new int[c_size+1];
memset( data, 0, sizeof(int)*(c_size+1) );
data浪費了第乙個空間data[0],為了簡化程式設計,使用data[100]。
使用篩選法的時候,將篩選過的元素置為-1。輸出結果的時候,僅列印data[i]的值為0的下標i。
for (int i=2; i<=data_size; i++)
下面給出整個演算法的完整**:
#include //use cin and cout
using namespace std;
//計算2到c_size範圍內的素數
const int c_size = 100;
void print(int *data, int data_size)
cout << endl; }
//使用篩選法計算素數
void cal_prime(int *data, int data_size)
}
int main()
有沒有更快的演算法呢?偶爾在圖書館看到了另外一種演算法,其大致思想如下:
1)在給定範圍內,挑出6n±1的數字;
2)計算根號下(給定範圍)內的所有素數(除了2,3)。比如要求出在100內的素數,先要求出在sqrt(100)內的素數,即10以內的素數(2,3,5,7)。拋去2,3,得到的結果為5,7.得到乙個檢驗陣列
3)將第一步得到的6n±1陣列的每個元素用檢驗陣列中的素數來測試,如果不能被檢驗陣列除盡,則該數必為素數。
證明我忘記了,在圖書館看到的。下面舉乙個例子,求100以內的素數。
1)將100以內6n±1的數字挑選出來。結果為:
5 7 11 13 17 19 23 25 29
31 35 37 41 43 47 49 53 55
59 61 65 67 71 73 77 79 83
85 89 91 95 97
2)計算出10以內的除了2、3外的素數,為5跟7.
3)分別用5和7來檢驗1)陣列中的數字。比如11不能被5和7整除,所以是素數,25能被5整除,所以不是素數。依次類推。得到的結果為:
5 7 11 13 17 19 23 25 29
31 35 37 41 43 47
495355
59 61 65 67 71 73
7779 83
85 89 91 9597
其中紅色數字為能被5或7整除的數字。
最後,加上2,3即為所有100以內的素數。
在程式設計的時候,求10以內的素數用篩選法,然後再用該演算法求出素數。具體程式如下:
#include //use cin and cout
#include //use vector
#include //use sqrt()
using namespace std;
//void cal_prime(int *data, int data_size)函式為之前定義的篩選法求素數
//初始化陣列,將6n+1,6n-1的數字加入陣列中
void initialize_vector(vector< int > &data)
else if (n == c_size)
data.push_back(n-1);
else
break;
i++; }
}
//快速計算該數是否為素數
//將該數字與檢驗陣列中的所有數字相除
int quick(int item, const vector< int > prime)
//如果檢驗陣列的數字都不能除盡該數
//說明是素數,返回該數字.
return item; }
void quick_cal_prime(void)
實際測試的時候,發現快速發並不」快」,為什麼呢?從理論上來說快速法減少了篩選法篩選的次數,估計有兩個地方阻礙了它的快速:1)快速法程式設計的時候使用了vector,效率上不如直接使用陣列快;2)快速法使用了多餘的語句(為了程式設計方便).
或許還有其它的原因,比如乙個根號運算.
如果大家有更好的演算法或者更高效的程式設計方法請告訴我,謝謝.
快速篩法求素數
stack queue的部落格 求素數是程式設計比賽中經常遇到的問題,最基本的方法是通過素數的定義直接判斷,只能被1和它本身整除的數就是素數了。這種方法適合判斷單個數是否為素數,當要求乙個範圍內素數而這個範圍又比較大時,這種方法就不太使用了,甚至程式要執行幾分鐘才能算出結果。篩法的思想是去除要求範圍...
快速篩法求素數
篩法的思想是去除要求範圍內所有的合數,剩下的就是素數了,而任何合數都可以表示為素數的乘積,因此如果已知乙個數為素數,則它的倍數都為合數。1 include2 using namespace std 3 define max 100000 4long long su max cnt 5bool isp...
一般篩法求素數 快速線性篩法求素數
素數總是乙個比較常涉及到的內容,掌握求素數的方法是一項基本功。基本原則就是題目如果只需要判斷少量數字是否為素數,直接列舉因子2 n 0.數 5 看看能否整除n。如果需要判斷的次數較多,則先用下面介紹的辦法預處理。首先先介紹一般的線性篩法求素數 void make prime num prime 0 ...