据我所知,使用“for”代码可能很清楚,但我想了解为什么这段代码不起作用。 此外,该代码是2008 MIT OCW课程练习的改编版,其中允许使用的唯一函数是算术函数,if,elif,else,print和while。 只是指出它,代码应该打印出前1000个素数。
print '2, ' #Print the prime 2 to set only odd primes.
primesofar=3 #Set 3 as the first prime
primecounter=1 #Mark 3 as the first prime to test until 1000, otherwise the while below should test to 1001
primesupport=1 #Create primesupport with a integer value
while primecounter<1000:
primesupport=primesofar/2 #Create a support counter for test the prime. This counter only had to have the half value of the supposed prime, because we only need to try to divide by the primes that are lower than the half of the suppposed prime. In fact it would be better to test for values that are lower than the square root of the supposed prime, but we can't use square root operation yet.
while primesupport>0:
if primesofar%primesupport == 0:
primesupport=-1 #If the remainer of the division is 0, the number isn't prime because it will have more than two divisors so we set primesupport as -1 to exit the while and increase the current primesofar to the next odd number.
primesofar=primesofar+2
elif primesupport==1: #If primesupport is 1, we tested all the numbers below the half of the supposed prime which means the number is prime. So we print it, set the while exit and increase the number of primes counted and go to the next odd number.
print primesofar+', '
primesofar=primesofar+2
primesupport=-1
primecounter=primecounter+1
else:
primesupport=primesupport-1
我很感谢快速响应,现在我认为可能在代码中有一个我看不到的中断。因此,我将尝试写下我认为代码应该做的事情,以便让您更容易指出我犯错误的地方。 开始吧: primesofar收到3; primecounter收到1,primesupport收到1。 第一个while测试的primecounter,因为primesupport小于1000,它进入循环。 然后,由于3/2 = 1,primesupport值更改为1 由于primesupport大于0,因此它进入第二个while循环。 if条件为真(3%1 = 0),因此代码输入if,将primesupport更改为-1并将primesofar增加2。(现在primesupport = -1和primesofar = 5) 这有一个问题,因为它离开而没有打印3,但让我们继续。 当它返回到第二个时它将收到一个False,因为-1不大于0。 这将使代码测试成为第一个,并且由于primecounter没有被更改,它将再次进入循环。 Primesupport现在将获得2(因为5/2 = 2) 它将进入第二个循环并通过所有循环直到其他条件。 Primesupport将减少一个(primesupport now = 1),while循环将继续进入elif。 这将打印5 将primesofar增加到7 减少primesupport以离开while循环并增加primecounter,返回第一个循环并重新开始。 我承认,除了没有按预期打印的3,我无法看到我在这里犯了错误。希望你能指出我。
谢谢大家的帮助,尤其是FallenAngel,John Machin,DiamRem和Karl Knechtel指出错误并展示调试方法。
答案 0 :(得分:1)
我认为这是问题所在:
你因为primesofar = 3而在python 3/2 = 1时被卡住了,所以如果primesofar%primesupport == 0:这是真的,因为python中的1%1 = 0,如果primesofar是1,那么代码是+2,然后primesofar又是3,你在永恒中从一段时间跳到另一段。
答案 1 :(得分:1)
if primesofar%primesupport == 0:
primesupport=-1
当代码到达这一点时,内部循环将被破坏,而primecounter
不会发生变化。代码将使用相同的primecounter
值重复相同的步骤,并且必须达到相同的点;没有办法打破外循环。
(虽然打破循环的正确方法是使用break
。)
答案 2 :(得分:1)
我放置了一些print
语句,这是您的程序提供的输出:
primesupport 1
primesofar 5
primesupport 2
primesupport 1
primesofar 7
primesupport 3
primesupport 2
primesupport 1
primesofar 9
primesupport 4
primesupport 3
primesofar 11
primesupport 5
primesupport 4
primesupport 3
primesupport 2
primesupport 1
primesofar 13
primesupport 6
primesupport 5
primesupport 4
primesupport 3
primesupport 2
primesupport 1
primesofar 15
primesupport 7
primesupport 6
primesupport 5
primesofar 17
primesupport 8
primesupport 7
...
您的代码永远不会进入elif primesupport==1:
阻止,因此primecounter
永远不会增加...
用于测试的是:
while primecounter<2:
primesupport=primesofar/2
print 'primesupport %s' % primesupport
while primesupport>0:
if primesofar%primesupport == 0:
primesupport=-1
primesofar=primesofar+2
print 'primesofar %s' % primesofar
elif primesupport==1:
print primesofar+', '
primesofar=primesofar+2
primesupport=-1
primecounter=primecounter+1
print 'primesofar %s' % primesofar
print 'primesupport %s' % primesupport
print 'primecounter %s' % primecounter
else:
primesupport=primesupport-1
print 'primesupport %s' % primesupport
原因是,最终else
阻止将primesupport
减少到1,然后在下一个循环中,if primesofar%primesupport == 0:
返回true并执行该阻止,增加primesofar
2并开始新的素数检查...
答案 3 :(得分:1)
您需要在测试primesupport == 1
之前测试primesofar % primesupport == 0
,因为any_integer % 1
始终为0,而primesupport == 1
时要执行的代码不是发生。
当你修复它时,你会发现print primesofar+',
不起作用......你应该能够自己解决这个问题。
您可以部署的最基本的有效调试技术是:(1)使用一小组数据,以便您可以理解正在发生的事情,并且您可以使用铅笔和一张纸来检查结果(2)打印出正在发生的事情。
(1)while primecounter < 5:
(2)第二次之后,
print "sofar, support, count", primesofar, primesupport, primecounter
答案 4 :(得分:0)
你的代码的问题在于,每当primecounter变为1时,你正在检查primesofar%primesupport == 0,并且它总是这样做。所以你的程序永远不会进入elif和else部分。因此主要计数器永远不会增加。所以这将是一个无限循环。
你可以通过在primesofar%primesupport == 0之后放一个print语句来检查这个:
if primesofar%primesupport == 0:
print primesofar
您可以在检查primesofar%primesupport == 0之前检查primesupport == 1来更正它:
print '2, ' #Print the prime 2 to set only odd primes.
primesofar=3 #Set 3 as the first prime
primecounter=1 #Mark 3 as the first prime to test until 1000, otherwise the while below should test to 1001
primesupport=1 #Create primesupport with a integer value
while primecounter<1000:
primesupport=primesofar/2 #Create a support counter for test the prime. This counter only had to have the half value of the supposed prime, because we only need to try to divide by the primes that are lower than the half of the suppposed prime. In fact it would be better to test for values that are lower than the square root of the supposed prime, but we can't use square root operation yet.
while primesupport>0:
if primesupport==1: #If primesupport is 1, we tested all the numbers below the half of the supposed prime which means the number is prime. So we print it, set the while exit and increase the number of primes counted and go to the next odd number.
print primesofar
primesofar=primesofar+2
primesupport=-1
primecounter=primecounter+1
elif primesofar%primesupport == 0:
primesupport=-1 #If the remainer of the division is 0, the number isn't prime because it will have more than two divisors so we set primesupport as -1 to exit the while and increase the current primesofar to the next odd number.
primesofar=primesofar+2
else:
primesupport=primesupport-1
此代码将为您打印1000个素数。
顺便说一句,你不能用str连接str和int。你可以打印素数。 Print语句将自动添加换行符。