1. 程式人生 > >厄拉多塞素數篩選法

厄拉多塞素數篩選法

  厄拉多塞是一位古希臘數學家,他在尋找素數時,採用了一種與眾不同的方法——
  先將2-N的各數放入表中,然後在2的上面畫一個圓圈,然後劃去2的其他倍數;第一個既未畫圈又沒有被劃去的數是3,將它畫圈,再劃去3的其他倍數;現在既未畫圈又沒有被劃去的第一個數 是5,將它畫圈,並劃去5的其他倍數……依次類推,一直到所有小於或等於N的各數都畫了圈或劃去為止。這時,表中畫了圈的以及未劃去的那些數正好就是小於 N的素數。

  這很像一面篩子,把滿足條件的數留下來,把不滿足條件的數篩掉。由於這種方法是厄拉多塞首先發明的,所以,後人就把這種方法稱作厄拉多塞篩法。下面這張圖大致描述了篩選法的過程,圖片源自網路,侵刪。
在這裡插入圖片描述


  在計算機中,篩法可以用給陣列單元置零的方法來實現。具體來說就是:首先開一個數組:a[i],i=1,2,3,…,同時,令所有的陣列元素都等於下標 值,即a[i]=i,當i不是素數時,令a[i]=0 。當輸出結果時,只要判斷a[i]是否等於零即可,如果a[i]=0,則令i=i+1,檢查下一個a[i]。
篩法是計算機程式設計中常用的演算法之一。

#include<iostream>
#include<vector>
using namespace std;
vector<int> isprime;

void allprime(int n){ 
	isprime.
resize(n); fill(isprime.begin(),isprime.end(),1); for(int i=2;i*i<n;i++){ for(int j=i*i;j<n;j+=i){ isprime[j] = 0; } } } int main(){ int n; cin>>n; allprime(n); for(int i=1;i<=n;i++){ if(isprime[i]){ cout<<i<<" "; } } return 0; }

在這裡插入圖片描述

  相比於最常規的對每一個數從2開始取模判斷而言,這種方法時間效率更高,我們這裡不做證明,僅給出結論,厄拉多塞素數篩選的時間複雜度是 O

( n × l o g ( l o g ( n ) ) ) O(n\times log(log(n)))