您只需要检查可能的除数范围内的质数 - 例如,如果一个值不能被 2 整除,那么它也不能被 2 的任何倍数整除;对于其他每个素数和素数倍数也是如此。因此,在您的示例中,您可以检查2, 3, 5
- 您不需要检查4
,因为任何能被 4 整除的东西都必须能被 2 整除。因此,更快的方法是计算您感兴趣的任何范围内的素数,然后简单地计算哪个他们划分的价值观。
另一个加速是将您感兴趣的范围内的每个值添加到 a set
:当您发现它可以被您范围内的数字整除时,将其从集合中删除。然后,您应该只测试保留在集合中的数字 - 这将阻止您多次测试数字。
如果我们结合这两种方法,我们可以看到我们可以创建set
所有值的 a(因此在示例中,一个所有值都为 1 到 10 的集合),并简单地从该集合中删除第二个范围内每个素数的倍数。
编辑:正如 Patashu 指出的那样,如果除以给定值的素数不在集合中,这将不太有效。为了解决这个问题,我们可以对上述应用类似的算法:创建一个set
带有值[a, b]
的,对于 中的每个值set
,删除它的所有倍数。因此,对于下面在评论中给出的示例(带有[3, 6]
),我们将从 3 开始并删除它在集合中的倍数 - 所以6
。因此,我们需要测试的剩余值将[3, 4, 5]
是我们在这种情况下想要的。
Edit2:这是一个非常糟糕的、糟糕的实现,它没有被优化并且有可怕的变量名:
def find_non_factors():
a = 1
b = 1000000
x = 200
y = 1000
z = [True for p in range(x, y+1)]
for k, i in enumerate(z):
if i:
k += x
n = 2
while n * k < y + 1:
z[(n*k) - x] = False
n += 1
k = {p for p in range(a, b+1)}
for p, v in enumerate(z):
if v:
t = p + x
n = 1
while n * t < (b + 1):
if (n * t) in k:
k.remove(n * t)
n += 1
return k
使用这些数字尝试您的原始实现。在我的电脑上花费 > 1 分钟。此实现需要不到 2 秒的时间。