我想在range(old_number + 1 , 2*old_number)
内找到最大的质数
到目前为止,这是我的代码:
def get_nearest_prime(self, old_number):
for num in range(old_number + 1, 2 * old_number) :
for i in range(2,num):
if num % i == 0:
break
return num
当我打电话给get_nearest_prime(13)
时
正确的输出应该是23
,而我的结果是25
。
有人可以帮助我解决这个问题吗?帮助将不胜感激!
答案 0 :(得分:1)
您可以进行很多更改,但是您应该进行哪些更改取决于您要完成的工作。就目前的代码而言,最大的问题是您正在使用break
成功识别素数,然后对该信息不做任何事情。这是一个最小的更改,可以做大致相同的事情。
def get_nearest_prime(old_number):
largest_prime = 0
for num in range(old_number + 1, 2 * old_number) :
for i in range(2,num):
if num % i == 0:
break
else:
largest_prime = num
return largest_prime
我们正在使用largest_prime
局部变量来跟踪找到的所有素数(因为您以递增顺序遍历它们)。每当您“正常”退出内部else
循环(即不点击for
子句)时,都会触发break
子句。换句话说,只要您找到素数。
这是一个更快的解决方案。
import numpy as np
def seive(n):
mask = np.ones(n+1)
mask[:2] = 0
for i in range(2, int(n**.5)+1):
if not mask[i]:
continue
mask[i*i::i] = 0
return np.argwhere(mask)
def get_nearest_prime(old_number):
try:
n = np.max(seive(2*old_number-1))
if n < old_number+1:
return None
return n
except ValueError:
return None
它的作用大致相同,但是它使用一种称为“ Eratosthenes筛”的算法来加快素数的查找速度(与您正在使用的“ trial division”相反)。它不是世界上最快的筛子,但是无需太多调整就可以理解。
在任何一种情况下,如果要多次调用此函数,您可能希望跟踪已找到的所有素数,因为计算它们很昂贵。在Python中,缓存既轻松又灵活,如果您确实需要提高速度,可以通过多种方法来实现。
请注意,我不同意您指定的范围始终包含质数。很好,如果可以的话,您可以使用更短的代码。类似于以下内容。
def get_nearest_prime(old_number):
return np.max(seive(2*old_number-1))
我并不完全同意您选择的名称,因为该间隔中最大的素数通常不是最接近old_number
的素数,但是无论如何,我认为这就是您要寻找的。 / p>
答案 1 :(得分:0)
您可以使用子列表来检查数字是否为质数,如果all(i % n for n in range(2, i))
表示该数字为prime
,这是由于从模取的所有值均为True
而不是0 。您可以从那里append
的值到一个名为primes
的列表中,然后取该列表的max
。
列表理解:
num = 13
l = [*range(num, (2*num)+1)]
print(max([i for i in l if all([i % n for n in range(2,i)])]))
展开:
num = 13
l = [*range(num, (2*num)+1)]
primes = []
for i in l:
if all([i % n for n in range(2, i)]):
primes.append(i)
print(max(primes))
23