python求素数代码_Python中的生成器生成素数

生成素数的最快方法是使用筛子.在这里,我们使用分段的Eratosthenes筛子按顺序逐个生成素数,没有最大值; ps是小于当前最大值的筛选素数列表,qs是当前段中相应ps的最小倍数的偏移量.

def genPrimes():

def isPrime(n):

if n % 2 == 0: return n == 2

d = 3

while d * d <= n:

if n % d == 0: return False

d += 2

return True

def init(): # change to Sieve of Eratosthenes

ps, qs, sieve = [], [], [True] * 50000

p, m = 3, 0

while p * p <= 100000:

if isPrime(p):

ps.insert(0, p)

qs.insert(0, p + (p-1) / 2)

m += 1

p += 2

for i in xrange(m):

for j in xrange(qs[i], 50000, ps[i]):

sieve[j] = False

return m, ps, qs, sieve

def advance(m, ps, qs, sieve, bottom):

for i in xrange(50000): sieve[i] = True

for i in xrange(m):

qs[i] = (qs[i] - 50000) % ps[i]

p = ps[0] + 2

while p * p <= bottom + 100000:

if isPrime(p):

ps.insert(0, p)

qs.insert(0, (p*p - bottom - 1)/2)

m += 1

p += 2

for i in xrange(m):

for j in xrange(qs[i], 50000, ps[i]):

sieve[j] = False

return m, ps, qs, sieve

m, ps, qs, sieve = init()

bottom, i = 0, 1

yield 2

while True:

if i == 50000:

bottom = bottom + 100000

m, ps, qs, sieve = advance(m, ps, qs, sieve, bottom)

i = 0

elif sieve[i]:

yield bottom + i + i + 1

i += 1

else: i += 1

使用试验除法的简单isPrime就足够了,因为它将限于n的第四个根.段大小2 * delta任意设置为100000.该方法需要O(sqrt n)空间用于筛分素数加上筛子的恒定空间.

它更慢但是节省了空间来生成带有方向盘的候选素数,并使用isPrime基于对基数为2,7和61的强伪测试来测试候选素的素数.这适用于2 ^ 32.

def genPrimes(): # valid to 2^32

def isPrime(n):

def isSpsp(n, a):

d, s = n-1, 0

while d % 2 == 0:

d /= 2; s += 1

t = pow(a,d,n)

if t == 1: return True

while s > 0:

if t == n-1: return True

t = (t*t) % n; s -= 1

return False

for p in [2, 7, 61]:

if n % p == 0: return n == p

if not isSpsp(n, p): return False

return True

w, wheel = 0, [1,2,2,4,2,4,2,4,6,2,6,4,2,4,\

6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,8,6,4,6,\

2,4,6,2,6,6,4,2,4,6,2,6,4,2,4,2,10,2,10]

p = 2; yield p

while True:

p = p + wheel[w]

w = 4 if w == 51 else w + 1

if isPrime(p): yield p

如果您对素数编程感兴趣,我在我的博客上谦虚地推荐this essay.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值