经过10分钟的工作,我写了一个功能如下.它返回一个低于参数的所有素数的列表.我已经使用了所有已知的编程和数学技巧,以尽可能快地完成此功能.为了找到低于一百万的所有素数,它需要大约2秒.
您是否认为有进一步优化的可能性?有任何想法吗?
def Primes(To):
if To<2:
return []
if To<3:
return [2]
Found=[2]
n=3
LastSqr=0
while n<=To:
k=0
Limit=len(Found)
IsPrime=True
while k<Limit:
if k>=LastSqr:
if Found[k]>pow(n,0.5):
LastSqr=k
break
if n%Found[k]==0:
IsPrime=False
break
k+=1
if IsPrime:
Found.append(n)
n+=1
return Found
Run Code Online (Sandbox Code Playgroud)
你可以使用一些技巧来加快速度,使用基本的mosstothenes筛子.一种是使用轮分解来跳过计算已知不是素数的数字.例如,除了2和3之外,所有质数都与1或5 mod 6一致.这意味着您根本不需要处理每6个数中的4个.
在下一个级别,所有素数都与1,7,11,13,17,19,23或29,模30一致.你可以丢掉每30个数中的22个.
以下是Erastothenes筛的简单实现,它不计算或存储偶数:
def basic_gen_primes(n):
"""Return a list of all primes less then or equal to n"""
if n < 2:
return []
# The sieve. Each entry i represents (2i + 1)
size = (n + 1) // 2
sieve = [True] * size
# 2(0) + 1 == 1 is not prime
sieve[0] = False
for i, value in enumerate(sieve):
if not value:
continue
p = 2*i + 1
# p is prime. Remove all of its multiples from the sieve
# p^2 == (2i + 1)(2i + 1) == (4i^2 + 4i + 1) == 2(2i^2 + 2i) + 1
multiple = 2 * i * i + 2 * i
if multiple >= size:
break
while multiple < size:
sieve[multiple] = False
multiple += p
return [2] + [2*i+1 for i, value in enumerate(sieve) if value]
Run Code Online (Sandbox Code Playgroud)
如上所述,您也可以使用更具异国情调的筛子.
| 归档时间: |
|
| 查看次数: |
160 次 |
| 最近记录: |