Eratosthenes篩選法(埃拉託斯特尼篩法)
阿新 • • 發佈:2018-12-17
Eratosthenes篩選法
主要用於求素數,時間複雜度為O(nloglogn),比尤拉篩選法要慢,故我一般不用改法。
由於一個合數總是可以分解成若干個質數的乘積,那麼如果把質數的倍數都去掉,那麼剩下的就是質數了.Eratosthenes篩選法的思想特別簡單:對於不超過n的每個非負整數p,刪除2p,3p,4p,...,當處理完所有數之後,還沒有被刪除的就是素數.如果用vis[i]表示i已經被刪除,則篩選法的程式碼可以寫成:
void isprime(int n)///篩選1-n的素數 { memset(vis,0,sizeof(vis)); for(int i = 2; i <= n; i++) for(int j = 2 * i; j <= n; j += i) vis[j] = 1; }
儘管程式碼已經相當高效了,但仍然可以進行改進.首先,在"對於不超過n的每個非負數p"中,p可以限定為素數--只需在第二重迴圈前加一個判斷if(!vis[i])即可.另外,內層迴圈也不必從i * 2開始--它已經在i = 2時被篩選了.改進後代碼如下:
void isprime(int n)///篩選1-n的素數 { memset(vis,0,sizeof(vis)); int m = sqrt(n + 0.5); for(int i = 2; i <= m; i++) { if(!vis[i]) { for(int j = i * i; j <= n; j += i) vis[j] = 1; } } }
Eratosthenes篩選法雖然效率高,但是Eratosthenes篩選法做了許多無用功,一個數會被篩到好幾次,最後的時間複雜度是O(nloglogn),對於普通素數演算法而言已經非常高效了,但尤拉篩選法的時間複雜度僅僅為O(n).