本文所利用的素數性質是:所有的素數都是奇數,且除2,3外其餘素數都出現在6n-1與6n+1這兩個數列中
具體**如下
首先建立乙個長度為n的false列表,再將索引為2,3,和6n+1、6n-1這兩個數列在列表中的值改為true
l =
[false]*n
l[2]=l[3]
=truel[5
:n:6]=
[true]*
len(l[
5:n:6]
)#數列6n-1l[7
:n:6]=
[true]*
len(l[
7:n:6]
)#數列6n+1
這兩數列中除了包含素數外還有一些非素數,所以我們需要想辦法將那些非素數對應的值改為false
6n-1 : 5 11 17 23 293541 47 53 59……
6n+1: 7 13 192531 37 434955 61……
不難發現這些數字都是前面那些素數的倍數,所以可以建立迴圈刪除倍數
for i in
range(5
,int
(n**
0.5)+1
,6):
if l[i]
: l[i*i:n:
2*i]=[
false]*
len(l[i*i:n:
2*i]
)#刪除倍數
for i in
range(7
,int
(n**
0.5)+1
,6):
if l[i]
: l[i*i:n:
2*i]=[
false]*
len(l[i*i:n:
2*i]
)#刪除倍數
刪除倍數這裡 l[ii:n:2i],從i的i倍開始,而不是從i的1倍開始,原因是i的j倍(j進行完上述工作,我們的列表l就成功記錄到了n以內所有的素數,我們只需要利用乙個迴圈將值為true的索引讀出來就好了
primes =
for i in
range
(n):
if l[i]
下面是整個**
#!/bin/env python
#-*-coding:utf-8-*-
import time
defprime
(n):
l =[false]*n
primes =
l[2]
=l[3]=
true
l[5:n:6]
=[true]*
len(l[
5:n:6]
)#數列6n-1
l[7:n:6]
=[true]*
len(l[
7:n:6]
)#數列6n+1
for i in
range(5
,int
(n**
0.5)+1
,6):
if l[i]
: l[i*i:n:
2*i]=[
false]*
len(l[i*i:n:
2*i]
)#刪除倍數
for i in
range(7
,int
(n**
0.5)+1
,6):
if l[i]
: l[i*i:n:
2*i]=[
false]*
len(l[i*i:n:
2*i]
)#刪除倍數
for i in
range
(n):
if l[i]
return primes
if __name__==
'__main__'
: t0=time.time(
) n =
10000001
primes = prime(n)
#print(primes)
print
('共找出%d個素數'
%len
(primes)
) runtime=time.time(
)-t0
print
('執行時間為'
,runtime, sep=
'')
程式執行截圖:
查詢10000000以內的素數用時約兩秒,還算可以。但感覺還有改進空間,在刪除倍數那裡,只刪除奇數倍實際上還是有不必要的工作的,因為不是所有的奇數倍都在6n-1和6n+1這兩個數列中。
求n以內的素數
求n以內素數。素數又稱質數,它是這樣的整數,它除了能表示為它自己和1的乘積以外,不能表示為任何其它兩個整數的乘積。有兩種方法 篩選法和開根號法 篩選法 從小到大篩去乙個已知素數的所有倍數。依次刪除可被2整除,3整除。的數字,剩下的則為素數 開根號法 如果乙個數 2 對這個數求平方根,如果這個數能被這...
題解 篩選N以內的素數
題目描述 用簡單素數篩選法求n以內的素數。輸入 n 輸出2 n 的素數 樣例輸入 30樣例輸出23 571113 1719 2329 題解 首先先解釋一下素數是什麼?素數一般指質數,質數是指在大於1的自然數中,除了1和它本身以外不再有其他因數的自然數。在一般領域,對正整數n,如果用2到n的開方之間的...
O n 線性篩選n以內的素數
o n 線性篩選n以內的素數 1 對於任何乙個素數p,都不可能表示為兩個數的乘積 2 對於任何乙個合數m p1 a1p2 a2 pm am,這裡p1 p2 m,都能使用p1 a1 1p2 a2 pm am p1進行篩選 1 fillchar prime,sizeof prime 1 2 prime ...