我需要从 2 开始按升序查找一定数量的素数。我有一个工作算法,它采用数字限制作为参数 - 它找到所有小于限制的素数。
例如 - 对于param 20
,它会返回2,3,5,7,11,13,17,19
,但我需要输入5
并获取2,3,5,7,11
。什么是最好的方法?我正在使用Eratosthenes的Sieve,并且没有办法限制数字删除部分,因为我不知道第195个素数有多大,因此我不知道是否应该删除所有2的倍数到1568或1268426.我希望问题很明确,谢谢你的帮助
答案 0 :(得分:5)
有几种方法可以做你想做的事。
素数定理表示小于 n 的素数的数量渐近等于 n / log( n )。您可以添加一个小缓冲区,然后执行Eratosthenes筛选,并抛弃超出限制的任何质数。
不是近似,而是有公式计算小于 n 的素数的确切数量而不列出素数。您可以使用其中一个公式来查找 n th prime,然后使用Sieve来制作素数列表。如果你想采用这种方法,Google可以使用“Legendre sum”和“Lehmer的公式”。
你可以使用分段的Eratosthenes筛子。筛分到一些方便的限制。如果你有答案,请停止。否则,选择下一个段,然后选择下一个段,依此类推,直到找到所需的素数。
有一种非常聪明的方法可以生成无限的素数列表,用优先级队列替换Eratosthenes的Sieve的位数组。谷歌为梅丽莎奥尼尔的论文真正的Eratosthenes筛选。
您可以看到所有这些算法here的完整解释和实现。
顺便说一下,第195个素数是1187.有247个素数小于1568个,97790个素数小于1268426个。
答案 1 :(得分:0)
你可以在Eratosthenes的原始Sieve背后采取相同的想法,但是迭代地做。
find_n_primes(num_primes):
primes = [2]
i = 3
while primes.size < num_primes:
is_prime = true
for p in primes:
if p > sqrt(i):
break
if i % p == 0:
is_prime = false
break
if is_prime:
primes.add(i)
i++
return primes
基本上,不是将每个数字的倍数增加到一个固定点,而是迭代n,并检查你已经找到的所有素数。
答案 2 :(得分:0)
前段时间,我写了一个处理素数的小模块(在处理Project Euler的时候满足了我的需求)。这非常快,因为它跟踪了它所见过的素数列表。这大大减少了计算时间。
这是您需要的主要例程(用python编写)。文档很平庸,但我希望这会有所帮助。
def primes(num, l=[]):
# l is the list of prime numbers you already have
# This is reused to check for primality of a number
if len(l) == 0: l = get_list() # Read from disk
# Check to see if a sublist can be created
e = l[-1]
if (num < e):
res = search.binary_low(l, num)
return l[:res[0]+1]
e = 6*(ceil(e/6))
lim = num + 1
# Extend the current list
for n in range(e, lim, 6):
m = n - 1
if isprime(m, l): l.append(m)
m = n + 1
if isprime(m, l): l.append(m)
# Save to pickle
set_list(l) # Write to disk
return l
您可以在此处找到相关的例程
https://github.com/pavanky/expo/blob/master/python/prime.py
https://github.com/pavanky/expo/blob/master/python/search.py