Python脚本未完成
我试着运行我的代码来解决第10个euler问题。我对python非常陌生,我的代码运行速度非常慢,在本例中,代码永远不会结束。任何帮助都将不胜感激。多谢各位Python脚本未完成,python,python-3.x,Python,Python 3.x,我试着运行我的代码来解决第10个euler问题。我对python非常陌生,我的代码运行速度非常慢,在本例中,代码永远不会结束。任何帮助都将不胜感激。多谢各位 primes = [2] number = 2 y=1 while y <=1: for i in primes: if number % i == 0: break else: if i == primes[-1]:
primes = [2]
number = 2
y=1
while y <=1:
for i in primes:
if number % i == 0:
break
else:
if i == primes[-1]:
primes.append(number)
if (primes[-1]) >= 2000000:
del primes[-1]
y += 2
number+=1
print(sum(primes))
primes=[2]
数字=2
y=1
y=2000000时:
del素数[-1]
y+=2
数字+=1
打印(总和(素数))
扰流器警报:以下是对Project Euler中问题10的回答
您的问题是,您的代码运行时间太长,这是因为它检查了太多的内容,并且运行时间太长。在体育问题中,你通常必须想出一个技巧,让你的程序能够足够快地得到结果。在这种情况下,您需要理解为什么不需要检查一个素数是否可以被一个大于该数平方根的素数整除
如果一个数x
可被一个大于x
平方根的素数p
整除,这意味着存在一个自然数n
,即n=x/p
,如果p
大于x
的平方根,则n
小于x
的平方根(想想这是为什么)。这意味着我们会发现数字x
也可以被小于x
平方根的数字n
整除。这意味着当我们检查所有小于x的平方根的数字时,我们已经发现x可以被n整除,因此没有必要检查任何大于n的平方根的数字,以便知道它是否是素数Q.E.D
这样可以节省大量的计算。下面是一个实现这一思想的python程序:
import math
primes = [2]
is_prime = True
# loop over all the ODD numbers from 3 to 2,000,000 (no need to check even numbers)
for number in xrange(3, 2000000 + 1, 2):
sqrt = math.sqrt(number)
# loop over all the primes we have so far
for prime in primes:
# if the number we are checking is divisible by a prime it is not prime and we can move on to the next number
if number % prime == 0:
# we set this value to false so that when we finish the loop we will be able to know if the number is prime or not
is_prime = False
break
# this line is where the clever part is, if we already checked `all the primes that are smaller than square root of x, and we did not find any primes that our number is divisible by, then we will not find any primes higher than the square root of the number that the number is divisible by`
if prime > sqrt:
break
if is_prime:
primes.append(number)
else:
is_prime = True
# we are done, print the answer
print sum(primes)
虽然我很欣赏@DonatPants的详细回答,但我认为解决方案太复杂了。首先,我们不需要计算较简单的平方时的
sqrt()
(即方程两边的平方)。其次,测试顺序似乎是向后的,如果数字%prime==0,为什么要在之后检查prime>sqrt
?如果prime>sqrt
,则不需要其他测试。那个布尔值是怎么回事?我解决这个问题的简单方法是:
primes = [2]
for number in range(3, 2000000 + 1, 2): # only test odd numbers
for prime in primes:
if prime * prime > number: # we're past sqrt, a prime!
primes.append(number)
break
if number % prime == 0: # a composite
break
print(sum(primes))
冗余计算prime*prime
效率低下。这对这个数字范围没有任何区别,但如果需要,您可以保留一个单独的正方形数组,枚举素数并使用生成的索引访问正方形,保存素数时保存。仅求素数平方比求所有数的平方根便宜:
primes = [2]
squares = [4]
for number in range(3, 2000000 + 1, 2):
for index, prime in enumerate(primes):
if squares[index] > number:
primes.append(number)
squares.append(number * number)
break
if number % prime == 0:
break
print(sum(primes))
我们浪费空间是为了避免浪费时间。但是同样,对于这个数字范围,它是不值得的。@Jacobr365这是不正确的,中断到行number+=1
,因此while循环的下一次迭代if语句将是if 3%2==0
,而else将执行。但是y值永远不会改变changes@DonatPants谢谢这就是我从手机上编辑得到的。我甚至没注意到那句话。删除注释。您的程序确实终止,但您没有给它足够的时间,我将行if(primes[-1])>=2000000:
更改为if(primes[-1])>=200:
,程序终止。让你的程序更有效率,这样它就会工作。你的答案更好,我这样写答案的原因是,它会有点类似于原始代码。关于“测试的顺序似乎是向后的”
,以及“我们不需要计算sqrt(),而简单的正方形就可以了”
,我同意你的方法更好。所以如果OP正在读这篇文章,我建议你使用这段代码,而不是我的。