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這個素數進行倍數標記時同樣會...