我有一个python类,它通过从第n-1个素数和增量开始生成第n个素数。然后除以列表中已经存在的所有素数(sqrt(候选))。 但是我的班级只是在某个地方陷入了无限循环,我无法弄清楚原因。
class prime_list():
def __init__(self):
self.primelst = [1]
self.n = 1
def increment(self):
self.n+=1
candidate = self.primelst[-1]+1
limit = int(math.floor(math.sqrt(candidate)))
prime = True
while True:
for p in self.primelst:
if p>limit:
break
if (candidate % p) == 0:
prime = False
break
if prime:
self.primelst.append(candidate)
return
else:
candidate += 1
limit = int(math.floor(math.sqrt(candidate)))
prime = True
if __name__=="__main__":
p = prime_list():
p.increment()
答案 0 :(得分:5)
问题是您将1
作为起始值放在主要列表中。 increment
函数会搜索不能被1
整除的数字。由于没有这样的数字,它会永远搜索。
您应该从2
作为初始最小素数开始,或者添加一个处理第一个素数生成的特殊情况。
答案 1 :(得分:2)
除了其他人描述的修正之外,还有一些注意事项:
self.n
并且不需要它,因为Python列表知道它们的长度。primelst
作为一个标识符是丑陋的:留下像这样的随机元音是高度非Pythonic,并且在标识符名称(“list”)中包含类型名称与鸭子类型的精神背道而驰。只需用复数命名容器。因此:
class prime_list():
def __init__(self):
self.primes = [2]
self.to_use = 1
def test(self, candidate):
# Check if we need to expand the list of used primes.
# Written a bit paranoid-ly
while len(self.primes) > self.to_use:
next = self.primes[self.to_use]
# Note the mathematical rearrangement. :)
if candidate <= next * next: self.to_use += 1
# Test all the primes <= sqrt(candidate).
return all(candidate % p != 0 for p in self.primes[:self.to_use])
def __iter__(self):
import itertools
for candidate in itertools.count(3):
if self.test(candidate):
self.primes.append(candidate)
yield candidate
if __name__ == "__main__":
my_primes = prime_list()
for p in my_primes:
print "Generated:", p
if p > 1000000: break
print "Number of primes generated:", len(my_primes.primes)
答案 2 :(得分:1)
这不是一个语言或算法问题,而是一个调试问题:)。 在循环中添加四个打印语句(每个条件分支一个),您将很快看到为什么您的程序似乎没有结束。 通过调查弄清楚自己发生了什么事情要好得多(教别人钓鱼而不是给他们钓鱼......)。
祝你好运!答案 3 :(得分:1)
Karl Knechtel的回答是正确的,但是迟钝;问题是to_use进展太快太快了。
这是我的修改版本 - 我已经删除了评论。
class prime_list():
def __init__(self):
self.primes = [2]
self.to_use = 0
def test(self, candidate):
next = self.primes[self.to_use]
if candidate >= next * next:
self.to_use += 1
print candidate, next
return all(candidate % p != 0 for p in self.primes[:self.to_use])
def __iter__(self):
import itertools
for candidate in itertools.count(3,2):
if self.test(candidate):
self.primes.append(candidate)
yield candidate
if __name__ == "__main__":
my_primes = prime_list()
# print my_primes.primes[0]
for p in my_primes:
print "Generated:", p
if p > 1000000: break
sum += p
print "Number of primes generated:", len(my_primes.primes)
答案 4 :(得分:0)
让我们一起跑:
// self.primelst = [1]
// self.n = 1
def increment(self):
self.n+=1 // self.n = 2
candidate = self.primelst[-1]+1 //candidate = 2
limit = int(math.floor(math.sqrt(candidate))) // limit = 1
prime = True // prime = True
while True:
for p in self.primelst: // p = 1
if p>limit: // False
break // Does not go here
if (candidate % p) == 0: // 2 % 1 == 0: True
prime = False // prime = False
break // breaks
if prime: // False
self.primelst.append(candidate) // Does not go here
return // Does not return
else: // Goes here
candidate += 1 // candidate = 3
limit = int(math.floor(math.sqrt(candidate))) // limit = 1
prime = True // prime = True
所以while循环无休止地重复。算法错了。