我试图创建一个菜单驱动的程序,它将计算并显示2和用户输入限制之间的所有素数。用户可以选择的第一个选项是"使用Sieve of Eratosthenes算法"创建从2到n的素数列表。第二个选项是"显示素数",第三个选项是退出。我的代码目前看起来像:
def main():
choice = displayMenu()
while choice!= '3':
if choice == '1':
sieve()
elif choice == '2':
prime
choice = displayMenu()
print("Thanks for playing!")
def displayMenu():
myChoice = '0'
while myChoice != '1' and myChoice != '2' and myChoice != '3':
print("""Please choose
1. Create a list of primes from 2 to n using
the Sieve of Eratosthenes algorithm
2. Display the prime numbers
3. Quit
""")
myChoice = input("Enter option--->")
if myChoice != '1' and myChoice != '2' and myChoice != '3':
print("Invalid option. Please select again.")
return myChoice
def sieve():
liste = [ ]
n = int(input("What number should I go up to?"))
choice = input("--->")
for primeCandidate in range (2,n):
isPrime = True
for divisor in range (2, primeCandidate):
if primeCandidate % divisor == 0:
isPrime = False
break
if isPrime:
liste.append(primeCandidate)
print(liste)
main()
我发现的是,当我从2到13打印质数时,例如它将其打印为
[3]
[3, 5]
[3, 5, 5]
[3, 5, 5, 5]
[3, 5, 5, 5, 7]
[3, 5, 5, 5, 7, 7]
[3, 5, 5, 5, 7, 7, 7]
[3, 5, 5, 5, 7, 7, 7, 7]
[3, 5, 5, 5, 7, 7, 7, 7, 7]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11, 11, 11, 11, 11]
[3, 5, 5, 5, 7, 7, 7, 7, 7, 9, 11, 11, 11, 11, 11, 11, 11, 11, 11]
有没有办法纠正这个并且只打印一次素数?
答案 0 :(得分:3)
sieve
函数中的缩进是错误的。这样,您可以在循环的每次迭代中将主要候选项添加到列表中,并立即打印列表。相反,您应该在测试 all 除数后,即在内循环之后添加主要候选者,并且只有在找到所有素数时才打印数字,即在外部循环之后。
试试这个(标记更改的行):
def sieve():
liste = [ ]
n = int(input("What number should I go up to?"))
choice = input("--->")
for primeCandidate in range (2,n):
isPrime = True
for divisor in range (2, primeCandidate):
if primeCandidate % divisor == 0:
isPrime = False
break
if isPrime: # only check isPrime after the loop completed
liste.append(primeCandidate)
print(liste) # only print the list once
此外,如注释中所述,您可能希望将实际算法与用户交互部分分开,并且可以使用更紧凑的all
函数和生成器表达式而不是内部循环。而且您不必检查所有数字primeCandidate
;相反,只需检查迄今已知的素数。:
def sieve(n): # pass n as parameter
liste = [ ]
for primeCandidate in range (2,n):
# use all with generator, and only check known primes
isPrime = all(primeCandidate % divisor != 0 for divisor in liste)
if isPrime:
liste.append(primeCandidate)
return liste # return, don't print
最后,请注意,严格来说,这是而不是 a Sieve of Erastothenes!一个真正的筛子将会越过"越过"标识为素数的倍数,而使用试验除法,您的代码几乎完全相反。两者都有效,但除法通常比乘法慢。
有关不同Prime数字算法的详细讨论,请参阅this related question。
答案 1 :(得分:0)
你有没有看过set
?然后为要添加到集合中的每个新整数执行set.add?
例如:
In [24]: a=[1]
In [25]: set(a)
Out[25]: {1}
In [26]: b=[1,1]
In [27]: set(b)
Out[27]: {1}
In [28]: c=set(b)
In [29]: c.add(1)
In [30]: c
Out[30]: {1}
In [31]: c.add(2)
In [32]: c
Out[32]: {1, 2}