什麼是eratosthenes篩法
考慮乙個常見的數論問題,指定乙個整數,求出不大於該數的所有質數。我們可以先寫乙個函式來判斷某個整數是否為質數,然後用它逐一判斷每個整數,而eratosthenes篩法比這種方法高效得多。
下面舉例來說明它的原理。觀察下面的彩圖(來自wikipedia),這裡是檢查120以內的所有質數。首先去掉1,因為1既不是質數也不是合數;然後2是質數,那麼2的倍數都肯定不是質數了,所以把2的倍數都塗成紅色(它們出局了,這裡是質數的遊戲...);接下來3沒有被塗掉,所以3是質數,同理把3的倍數塗成綠色;下乙個未塗掉的是5,所以5也是質數,同理把5的倍數塗掉;然後再塗掉7的倍數,剩下的就都是質數了。
怎麼,只要看2、3、5、7就夠了?這裡有兩個不那麼容易確定的問題,一是如何依次斷定3、5、7都是質數;二是為何塗掉7的倍數後就完成了。對於問題一,如果乙個整數不能被比它小的所有質數整除(這裡就是沒被塗掉),那麼我們就可以斷定它是質數。另外,該篩法的依據是,對於整數n,如果它不能被不大於n的平方根(sqrt(n))的任何質數所整除,那麼n就是質數。這樣就解決了問題二,對於120以內的整數,如果它不是質數,那麼它必定能被不大於10的質數(也就是2、3、5、7)所整除。
這樣我們可以確信上述演算法是正確的了,下面來看看如何實現它。
eratosthenes篩法的c#和f#實現
c# code - eratosthenes篩法下面是f#實現,其中getint和main是輔助函式://返回不大於n的質數構成的陣列
public
static
int sieveoferatosthenes(
intn)
//init sieve.
bool
sieve
=new
bool
[n +1];
for(
inti =2
; i
<
sieve.length; i
++)
//check it.
intupperbound
=convert.toint32(math.sqrt(n));
for(
inti =2
; i
<=
math.sqrt(n); i++)
}}//count it.
intcount =0
;for
(inti =
2; i
<
sieve.length; i++)
}//generate the result.
int primes
=new
int[count];
intindex =0
;for
(inti =
2; i
<
sieve.length; i++)
}return
primes;
}
f# code - eratosthenes篩法這兩段**也就勉強能實現演算法吧,有時間再考慮優化一下。#light
open
system
letgenerateprimes n =
match
n with|_
when
n <
2->[||
]|_ ->
//init sieve.
letsieve = [
|for
i in
0.. n
doyield
true|]
letisprime index = sieve.[index]
//check it.
letupperbound = convert.toint32(math.sqrt((
float
)n))
fori = 2to
upperbound
doif
isprime i
then
forj
in[i *
2.. i .. sieve.length - 1]
dosieve.[j]
false
letmutable
count =
0for
i = 2to
sieve.length - 1do
ifisprime i
then
count
count +
1let
primes = array.create count
0let
mutable
index =
0for
i = 2to
sieve.length - 1do
ifisprime i
then
primes.[index]
iindex
index +
1primes
letgetint() =
convert.toint32(console.readline())
letmain() =
leti = getint()
letprimes = generateprimes i
console.writeline(
"find prime(s)
", primes.length)
print_any primes
main()
console.read()
(要了解本人所寫的其它f#隨筆請檢視 f#系列隨筆索引)
參考:sieve of eratosthenes
Eratosthenes篩法(素數篩)
最一般的素數篩思想很簡單,對於不超過maxx的每個非負整數p,刪除2p,3p,4p,然後剩下的就是素數,複雜度o nlogn 因為對內層迴圈n 2 n 3 n n 小於 1 1 2 1 3 1 n ln n 1 其中 為尤拉常數 0.577218 應當注意,1不是素數哦 這樣已經不慢,但由於所有非素...
Eratosthenes篩法求素數
篩法的思想 對於不超過n的每個非負整數p,刪除2p,3p,4p,5p,當處理完所有數之後,還沒有被刪除的數就是素數 這是簡易版的篩法,也最好理解 for int i 2 i n i for int j i 2 j n j i vis j false 還可以繼續改進,為什麼呢?給定外層迴圈變數i,內層...
利用Eratosthenes篩選法計算質數
演算法第1步就是寫下從3至某個上限之間的所有奇數。在演算法的剩餘部分,遍歷整個列表並剔除所有不是質數的奇數。在3之後把每逢第3個數 3的倍數 剔除。完成這一步之後,輪到5,將所有5的倍數剔除。這樣依次類推 反覆進行,最後列表中未被剔除的數均為質數。這裡可能讀者會有問題了,為什麼輪到4 6 8 10等...