如何在Python中使用递归查找素数

时间:2016-05-08 02:09:19

标签: python python-3.x recursion primes

我必须使用递归来确定数字(N)是否为素数,不允许循环。我尝试将使用for循环的常用代码转换为递归代码,但它的行为并不相同。此功能包含在另一个功能中,该功能是另一个功能的一部分。只应使用和传递参数a和N. 这是我的功能。

a=2
def is_prime(a,N):
prime = True
if N <=1:
    return 
else:
    if a >= N:
        return 
    else:
        if N == 2: 
            prime = True
            print(N)
            return 
        elif (N % a) == 0:
            prime = False
            return is_prime(a+1,N)
        else:
            prime = True
            print(N)

return

我相信这个错误就在这里。

elif (N % a) == 0:
            prime = False
            return is_prime(a+1,N)
        else:
            prime = True
            print(N)

以下是我尝试转换的代码。

if num > 1:
   for i in range(2,num):
      if (num % i) == 0:
         print(num,"is not a prime number")
         print(i,"times",num//i,"is",num)
         break
   else:
      print(num,"is a prime number")

else:
   print(num,"is not a prime number")

6 个答案:

答案 0 :(得分:2)

您的解决方案已接近完成,只需进行一些更改即可使其正常运行。

def is_prime(a,N):
    print(a, N)
    if N <= 1:
        return 
    else:
        if a >= N:
            print(N)
        else:
            if N == 2: 
                print(N)
            elif (N % a) == 0:
                return False
            else:
                return is_prime(a+1,N)

    return False

你没有给出调用这个函数的任何例子,但我认为它总是被调用a为2,因为任何其他值都没有意义。因此,如果你像这样运行上面的函数,你应该得到正确的输出:

print(is_prime(2, 7))  => True
print(is_prime(2, 4))  => False
print(is_prime(2, 37)) => True

我认为你对递归的工作原理有误解,你在函数体中分配了这个prime变量,但是从不对它做任何事情。也许你的困惑来自于对Python范围的误解。 prime变量不会在调用之间“共享”,每次都会创建一个新的prime

编辑:没有意识到你希望函数只打印出素数,如果它是素数,则相应地更改了代码。

答案 1 :(得分:1)

你的函数有时会返回某些东西,有时会返回 nothing - 它应该是全部的一个或另一个,而不是两者。在这种情况下,points看起来像一个布尔函数,所以它应该返回True或False。我们将打印留给来电者:

is_prime()

保持简单。仔细考虑每个可能的情况。避免不必要地增加压痕深度,这会使您的代码更复杂。

上述解决方案试图通过避免偶数(除数和数字)并将除数限制为数字的平方根来加速素数检测。这可能很重要,如果没有这些优化,递归解决方案可能会在N = 1,000附近耗尽调用堆栈空间,而上述应该在不扩展调用堆栈的情况下转到N = 1,000,000。

答案 2 :(得分:1)

def prime(n,j):
    if(n<2):
        return False
    if(j==n):
        return True
    if(n%j==0):
        return False
    return prime(n,j+1)

print(prime(n,2))

如果一个数字只能被自身和1整除,则称为质数。 因此,如果n被(2,3,4,.. n-1)中的任何一个整除,则从2迭代到n-1,返回False。
如果j == n,那么(2,3,4 ... n-1)中没有被n整除的数字,因此它是素数。

答案 3 :(得分:0)

由于我们的目标是打印该号码,以防它首先使用该号码。您的代码中已经有条件但是没有打印:

if a >= N:
    print(N)
    return

接下来,我们需要处理N > 1

的所有情况
if N == 2: 
    prime = True
    print(N)
    return 
elif (N % a) == 0:
    prime = False
    return is_prime(a+1,N)
else:
    prime = True
    print(N)

首先检查,if N == 2是不必要的,因为之前已经有一个块处理N为素数的所有情况,因此可以将其删除。那说拥有它并没有造成任何伤害。

检查N是否可被a整除的下一个块应该终止递归。既然你知道N不是素数,那么就应该停在那里。

N不能被a整除时执行的最终块应该执行递归。现在看来,递归就在N % a != 0时立即停止,这显然是错误的。

这是一个具有上述修改和清理的工作样本:

def is_prime(N, a=2):
    if N <= 1:
        return
    elif a >= N:
        print(N)
    elif N % a != 0:
        is_prime(N, a + 1)

答案 4 :(得分:0)

打印给定范围内的素数列表

l=[]
def primenum(x,y):
    global l
    if x==y:
        print(l)
    else:
        m=0
        for i in range(1,x+1):   
            if x%i==0:
                m+=1
        if m==2 or x==1:
            l+=[x,]
            return primenum(x+1,y)
        else:
            primenum(x+1,y)

答案 5 :(得分:0)

def is_prime(n):
  def prime_helper(n, x):
    if n == 1:
      return False
    elif n % x == 0:
      return False
    else:
      return prime_helper(n , x+1) if x * x <= n else True 
  return prime_helper(n, 2)

如果您不想使用助手功能

def is_prime(n, x=2):
    if n == 1:
      return False
    elif n % x == 0:
      return False
    else:
      return is_prime(n , x+1) if x * x <= n else True 

此外,您无需检查(1-N)之间的所有数字,而只需检查sqrt(n)。 您可以将迭代方法更改为

for循环

from math import sqrt 
def is_prime(n):
  if n == 1:
     return False
  for i in range(2, round(sqrt(n)) + 1):
     if n % i == 0:
        return False
  return True

while循环

def is_prime(n):
  if n == 1:
    return False
  i = 2
  while i * i <= n:
     if n % i == 0:
        return False
     i += 1
  return True