这是我能提出的最佳算法.
def get_primes(n):
numbers = set(range(n, 1, -1))
primes = []
while numbers:
p = numbers.pop()
primes.append(p)
numbers.difference_update(set(range(p*2, n+1, p)))
return primes
>>> timeit.Timer(stmt='get_primes.get_primes(1000000)', setup='import get_primes').timeit(1)
1.1499958793645562
Run Code Online (Sandbox Code Playgroud)
可以做得更快吗?
此代码有一个缺陷:由于numbers是无序集,因此无法保证numbers.pop()从集中删除最小数字.然而,它对某些输入数字起作用(至少对我而言):
>>> sum(get_primes(2000000))
142913828922L
#That's the correct sum of all numbers below 2 million
>>> 529 in get_primes(1000)
False
>>> 529 in get_primes(530)
True
Run Code Online (Sandbox Code Playgroud) 我在维基百科上读过关于阿特金的筛选,但维基目前是有限的.我正在寻找高水平的阿特金筛选和Java中的一个例子的解释.
谢谢.
我一直在努力学习生成素数的算法,我在维基百科上遇到了阿特金的Sieve.我理解算法的几乎所有部分,除了少数几个.以下是问题:
以下是维基百科的伪代码供参考:
// arbitrary search limit
limit ? 1000000
// initialize the sieve
for i in [5, limit]: is_prime(i) ? false
// put in candidate primes:
// integers which have an odd number of
// representations by certain quadratic forms
for (x, y) in [1, ?limit] × [1, ?limit]:
n ? 4x²+y²
if (n ? limit) and (n mod 12 = 1 or …Run Code Online (Sandbox Code Playgroud) 我不知道这是否可能,但我只是想问一下。我的数学和算法技能有点让我失望:P
问题是我现在有这个类可以生成达到一定限制的素数:
public class Atkin : IEnumerable<ulong>
{
private readonly List<ulong> primes;
private readonly ulong limit;
public Atkin(ulong limit)
{
this.limit = limit;
primes = new List<ulong>();
}
private void FindPrimes()
{
var isPrime = new bool[limit + 1];
var sqrt = Math.Sqrt(limit);
for (ulong x = 1; x <= sqrt; x++)
for (ulong y = 1; y <= sqrt; y++)
{
var n = 4*x*x + y*y;
if (n <= limit && (n % 12 == 1 || n …Run Code Online (Sandbox Code Playgroud) 我有一个由以下列表理解初始化的无限素数列表:
primes = [x | x <- [2..], 0 `notElem` map (x `mod`) [2..(x `quot` 2)]]
Run Code Online (Sandbox Code Playgroud)
这允许我做出检查,17 `elem` primes以确认17是素数.但是,当我检查列表中是否存在非素数时,程序不会停止计算.我认为这是因为它没有意识到如果在大于数字的素数之前在列表中找不到该数字,则在列表中的任何地方都找不到它.因此,无论如何,在Haskell中是否向编译器表明列表仅包含升序数,因此如果elem检查到达列表中的数字大于其第一个参数,则检查将知道停止并返回false?