我写了下面的代码,应该检查输入的号码是否是素数,但是有一个问题我无法通过:
def main():
n = input("Please enter a number:")
is_prime(n)
def is_prime(a):
x = True
for i in (2, a):
while x:
if a%i == 0:
x = False
else:
x = True
if x:
print "prime"
else:
print "not prime"
main()
如果输入的数字不是素数,则显示“非素数”,因为它应该是,但如果数字是素数,则它不显示任何内容。你能帮帮我吗?
答案 0 :(得分:93)
以下是我对这个问题的看法:
from math import sqrt; from itertools import count, islice
def isPrime(n):
return n > 1 and all(n%i for i in islice(count(2), int(sqrt(n)-1)))
这是一个非常简单和简洁的算法,因此它并不意味着接近最快或最优的素数检查算法。它的时间复杂度为O(sqrt(n))
。 前往here了解更多关于正确完成的素性测试及其历史。
我会给你一些关于那些将检查素数的几乎深奥的单行代码的内容:
首先,使用range()
确实是一个坏主意,因为它会创建一个使用大量内存的数字列表。使用xrange()
会更好,因为它会创建一个生成器,它只需要记住您提供的初始参数,并在运行中生成每个数字。如果你正在使用
默认情况下,Python 3或更高版本range()
已转换为生成器。顺便说一句,这根本不是最好的解决方案:尝试为xrange(n)
调用n
,使n > 231-1
(这是C long
的最大值)提出OverflowError
。因此创建范围生成器的最佳方法是使用itertools
:
xrange(2147483647+1) # OverflowError
from itertools import count, islice
count(1) # Count from 1 to infinity with step=+1
islice(count(1), 2147483648) # Count from 1 to 2^31 with step=+1
islice(count(1, 3), 2147483648) # Count from 1 to 3*2^31 with step=+3
如果您想检查n
是否为素数,则实际上不需要一直到n
。您可以大大减少测试,只检查从2到√(n)
(n
的平方根)。这是一个例子:
让我们找到n = 100
的所有除数,并将它们列在表中:
2 x 50 = 100
4 x 25 = 100
5 x 20 = 100
10 x 10 = 100 <-- sqrt(100)
20 x 5 = 100
25 x 4 = 100
50 x 2 = 100
您很容易注意到,{strong>在n
的平方根之后,我们找到的所有除数实际上已经找到了。例如20
已经找到了100/5
。数字的平方根是我们发现的除数开始重复的确切中点。因此,要检查数字是否为素数,您只需要检查2到sqrt(n)
。
为什么选择sqrt(n)-1
,而不只是sqrt(n)
?那是因为提供给itertools.islice
对象的第二个参数是要执行的迭代次数。 {strong> islice(count(a), b)
在b
次迭代后停止。这就是为什么:
for number in islice(count(10), 2):
print number,
# Will print: 10 11
for number in islice(count(1, 3), 10):
print number,
# Will print: 1 4 7 10 13 16 19 22 25 28
函数all(...)
与以下内容相同:
def all(iterable):
for element in iterable:
if not element:
return False
return True
字面检查iterable
中的所有数字,当数字评估为False
时返回False
(这意味着只有数字为零) )。那我们为什么要用呢?首先,我们不需要使用额外的索引变量(就像我们使用循环一样),除此之外:只是为了简洁,没有真正需要它,但它看起来不那么笨重一行代码而不是几行嵌套行。
我包含isPrime()
函数的“解压缩”版本,以便更容易理解和阅读:
from math import sqrt
from itertools import count, islice
def isPrime(n):
if n < 2:
return False
for number in islice(count(2), int(sqrt(n) - 1)):
if n % number == 0:
return False
return True
答案 1 :(得分:69)
有许多有效的方法可以测试primality(这不是其中之一),但你编写的循环可以用Python简洁地重写:
def is_prime(a):
return all(a % i for i in xrange(2, a))
也就是说,如果a和2之间的所有数字(不包括在内)在分成a时给出非零余数,则a为素数。
答案 2 :(得分:29)
如果只有少量查询,这是查看数字是否为素数的最有效方法。如果你问了很多数字,如果他们是最好的尝试Sieve of Eratosthenes。
import math
def is_prime(n):
if n == 2:
return True
if n % 2 == 0 or n <= 1:
return False
sqr = int(math.sqrt(n)) + 1
for divisor in range(3, sqr, 2):
if n % divisor == 0:
return False
return True
答案 3 :(得分:8)
如果a
是素数,则代码中的while x:
将永久运行,因为x
将保持True
。
那么为什么那里有while
?
我认为你想在找到一个因子时结束for循环,但不知道怎么做,所以你添加了它,因为它有一个条件。所以这就是你如何做到的:
def is_prime(a):
x = True
for i in range(2, a):
if a%i == 0:
x = False
break # ends the for loop
# no else block because it does nothing ...
if x:
print "prime"
else:
print "not prime"
答案 4 :(得分:0)
def prime(x):
# check that number is greater that 1
if x > 1:
for i in range(2, x + 1):
# check that only x and 1 can evenly divide x
if x % i == 0 and i != x and i != 1:
return False
else:
return True
else:
return False # if number is negative
答案 5 :(得分:0)
def is_prime(x):
n = 2
if x < n:
return False
else:
while n < x:
print n
if x % n == 0:
return False
break
n = n + 1
else:
return True
答案 6 :(得分:-3)
a = input('inter a number: ')
s = 0
if a == 1:
print a, 'is a prime'
else :
for i in range (2, a ):
if a%i == 0:
print a,' is not a prime number'
s = 'true'
break
if s == 0 : print a,' is a prime number'
它与我合作很好:D
答案 7 :(得分:-4)
def isPrime(x):
if x<2:
return False
for i in range(2,x):
if not x%i:
return False
return True
print isPrime(2)
真的 print isPrime(3)
真的 print isPrime(9)
假