素數篩選法在很多大牛的部落格中都有帖子,有的甚至給出3種方法。。。本文只是給我自己和能看到這篇文章的人分享一下我個人理解到現在的素數篩選法。
素數篩選法常常的問題背景是給出乙個非負整數n,求小於(等於)n的非負整數內有幾個素數。
下面先給出素數篩選法的原理:開出乙個大小為n的bool型陣列arr,全置為false。此時用陣列下標(0 to n-1)來代表小於等於n的全部非負整數。而其中某個數值arr[i]代表這個數是否為合數,即一開始我們假設所有數是素數。不做任何優化的素數篩選,第一層迴圈index == 2 to n -1。第二層不斷倍增index(index*2 index*3...),這樣新得到的下標一定是合數,將其內容置true。這裡有三個注意的地方,一是注意下標不要越界,二要注意第一層迴圈要判斷當前位置陣列的內容,如果已經被置為true,證明有更小的index1 * j == index,則index倍增的結果都可以由index1倍增得到,此時再去倍增index是徒勞的。三是0和1既不是合數也不是素數本身不參與倍增和個數統計。為了方便理解,我從leetcode上一道有關素數篩選的題目搞到一張解釋素數篩選過程的圖如下
下面給出以c++實現的**
int countprimes(int n) }}
int count = 0;
for(int i = 2;i < n;++i)
return count;
}
這裡可以做一些優化,全部是圍繞有且只有乙個偶素數2.其他偶數可以不參與篩選和最後的素數個數統計,**如下:
int countprimes(int n) }}
int count = n >= 3 ? 1 : 0;//統計時根據問題規模決定count中包不包括2
for (int i = 3; i < n; i += 2)
return count;
}
這就是我想分享的結果啦。。。優化的**跑leetcode測試用例時常減少了一半還多。。。開心
開帖方便自己隨時回爐。如果對大家有幫助就更好了,也不是什麼大神,只能搞搞這種小問題。。。
素數篩選法
篩選素數法 搞acm的都知道,素數是數論中必不可少的知識,也是必須要掌握的,關於素數的篩選有好幾種方法,下面一一道來,寫的不好還請提出。第一種是最常規的做法 int main if j sqrt i cout 這種方法肯定是比第一種快的,至於快多少大家可以比較一下,注意到裡面的for迴圈是到sqrt...
素數篩選法
素數篩選法差不多是打標,用前面確定的質數篩選掉後面的合數,然後遍歷下來所有的合數都被篩選掉了,剩下的都是素數。int vis maxn for int i 2 i n i for int j i 2 j n j i vis j 1 這是沒有優化的素數篩選法,也已經很快了,時間複雜度是n log n。...
素數篩選法
素數,是指因子只包含1和其本身的數,那麼,我們怎麼判斷素數呢?以下 均基於打表 1 1e6 的基礎上完成 素數的定義就是乙個數的因子只包含1和其本身,那麼我們直接就按照定義寫 include include define maxn 1000000 10 int pri maxn int isprim...