詳解利用filter函式求解素數 埃氏篩選

2021-10-03 17:19:57 字數 2332 閱讀 4379

filter函式(篩選函式):

有兩個引數,第乙個引數是乙個函式,第二個函式是乙個序列。把函式依次作用於序列的元素,根據返回值判斷保留還是丟棄這個元素。filter函式最後返回的是乙個filter物件(迭代器物件)。

計算素數的乙個方法就是埃氏篩法,它的演算法理解起來非常簡單:

首先,列出從2開始的所有自然數,構造乙個序列:

2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, …

取序列的第乙個數2,它一定是素數,然後用2把序列的2的倍數篩掉:

3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,15, 16, 17, 18, 19, 20, …

取新序列的第乙個數3,它一定是素數,然後用3把序列的3的倍數篩掉:

5,6,7 ,8,9,10,11,12,13,14,15, 16,17,18, 19, …

取新序列的第乙個數5,然後用5把序列的5的倍數篩掉:

7, 8,9,10,11,12,13,14,15,16, 17,18,19,20, …

不斷篩下去,就可以得到所有的素數。

用python來實現這個演算法,可以先構造乙個從3開始的奇數序列:

def

_odd_iter()

: n =

1while

true

: n = n +

2yield n

註解:

_odd_iter()函式因為含有yield關鍵字,變成了乙個生成器函式,返回的是乙個生成器物件

然後再定乙個篩選函式:

def

_not_divisible

(n):

return

lambda x: x % n >

0

註解:

這個篩選函式返回篩選規則。

最後,定義乙個生成器.

def

primes()

:# 先返回2

yield

2 it = _odd_iter(

)# 初始序列

while

true

: n =

next

(it)

# 返回序列的第乙個數

yield n

it =

filter

(_not_divisible(n)

,it)

#構造新序列

註解:

這個生成器先返回第乙個素數2,然後,利用filter()不斷產生篩選後的新數列。

由於primes()是乙個無限序列,所以呼叫時需要設定乙個退出迴圈的條件。

for n in primes():

if n<

100:

print

(n)else

:break

註解

iterator是惰性計算序列,所以可以在python中表示「」全體自然數「」,「」全體素數「」這樣的序列。

故:上面的程式其實就可理解成這樣。

首先有乙個it生成器(代表從3開始的全體奇數序列)。

然後n=next(it)去除第乙個數,就是3(是素數)列印出來。

it=filter(_not_divisible(n),it):

構造乙個新序列,就是將已經取出3之後的奇數序列,通過_not_divisible(n)返回的篩選規則給生成的乙個新的filter迭代器物件(你可以理解成就是乙個新的生成器)然後迴圈 n = next(it)取出新物件的第乙個數(肯定是素數)。。。後面就是一直迴圈了.

埃氏篩法 素數篩

埃式篩法 給定乙個正整數n n 10 6 問n以內有多少個素數?做法 做法其實很簡單,首先將2到n範圍內的整數寫下來,其中2是最小的素數。將表中所有的2的倍數劃去,表中剩下的最小的數字就是3,他不能被更小的數整除,所以3是素數。再將表中所有的3的倍數劃去 以此類推,如果表中剩餘的最小的數是m,那麼m...

素數 埃氏篩法

題目 求2 100以內的素數。素數 prime number 又稱質數,是指乙個大於1的自然數,除了1和它本身外,不能被整除以其他自然數。解法一 根據素數的定義,即用該數除比其小的數 1除外 都不能除盡,即為素數 public class prime if i n system.out.print ...

素數篩法(埃氏篩,線性篩)

時間複雜度o nloglogn void prime int b prime i 1則是合數 原理很簡單,所有合數可以表示為乙個質數跟另乙個數的積,列舉每個已知素數的倍數就能標記完。但很明顯,這樣做會有重複。比如12 3 4 2 6,在2這個素數進行倍數標記時會標記,在3這個素數進行倍數標記時同樣會...