[英]How do I find a prime number using recursion in Python
I have to find out whether number(N) is a prime or not using recursion, no loops are allowed.我必须使用递归找出 number(N) 是否是素数,不允许循环。 I've tried converting the usual code that uses a for loop to a recursive one, but it's not behaving the same.我尝试将使用 for 循环的常用代码转换为递归代码,但它的行为不一样。 This function is included in another function, which is part of another function.此功能包含在另一个功能中,该功能是另一个功能的一部分。 only parameters a and N should be used and passed Here is my function.只应使用和传递参数 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
I believe the bug is somewhere here.我相信这个错误在这里的某个地方。
elif (N % a) == 0:
prime = False
return is_prime(a+1,N)
else:
prime = True
print(N)
Here is the code I tried to convert.这是我尝试转换的代码。
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")
Your solution is close, with just a few changes needed to make it work.您的解决方案很接近,只需进行一些更改即可使其正常工作。
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
You didn't give any examples of calling this function, but I assume it's always called with a
being 2, since any other value wouldn't make sense.您没有给出调用此函数的任何示例,但我认为它总是a
2 的形式调用,因为任何其他值都没有意义。 So if you run the above function like so, you should get the right output:所以如果你像这样运行上面的函数,你应该得到正确的输出:
print(is_prime(2, 7)) => True
print(is_prime(2, 4)) => False
print(is_prime(2, 37)) => True
I think you have a misunderstanding of how recursion works, you're assigning this prime
variable in the body of the function, but never doing anything with it.我认为您对递归的工作方式有误解,您在函数体中分配了这个prime
变量,但从未对它做任何事情。 Maybe your confusion comes from a misunderstanding of scopes in Python.也许你的困惑来自对 Python 中作用域的误解。 That prime
variable will not be 'shared' across invocations, it will just create a new prime
every time.该prime
变量不会在调用之间“共享”,它只会每次都创建一个新的prime
。
EDIT: Didn't realize you wanted the function to just print out the prime if it's a prime, changed the code accordingly.编辑:没有意识到您希望该函数仅打印出素数,如果它是素数,则相应地更改了代码。
Your function sometimes returns something and sometimes returns nothing -- it should be either all one or the other, not both.你的函数有时会返回一些东西,有时什么也不返回——它应该是一个或另一个,而不是两者。 In this case is_prime()
looks like a boolean function so it should return True or False.在这种情况下is_prime()
看起来像一个布尔函数,所以它应该返回 True 或 False。 We'll leave the printing to the caller:我们将打印留给调用者:
def is_prime(N, a=3):
if N == 2: # special case
prime = True
elif N <= 1 or N % 2 == 0: # too small or even
prime = False
elif a * a > N: # tried all divisors to sqrt, must be prime
prime = True
elif (N % a) == 0: # divides evenly, not a prime
prime = False
else: # can't tell yet, recursively try the next (odd) divisor
prime = is_prime(N, a+2)
return prime
for x in range(100):
if is_prime(x):
print(x)
Keep it simple.把事情简单化。 Think through each possible case.仔细考虑每一个可能的情况。 Avoid increasing the indention depth unnecessarily, it makes your code more complicated.避免不必要地增加缩进深度,这会使您的代码更加复杂。
The above solution tries to speed up prime detection by avoiding even numbers (both divisor and number) and limiting the divisor to the square root of the number.上述解决方案试图通过避免偶数(除数和数字)并将除数限制为数字的平方根来加速素数检测。 This can matter as without these optimizations, a recursive solution will likely run out of call stack space at around N=1,000 whereas the above should go to N=1,000,000 without expanding the call stack.这很重要,因为如果没有这些优化,递归解决方案可能会在 N=1,000 左右耗尽调用堆栈空间,而上面的解决方案应该在不扩展调用堆栈的情况下达到 N=1,000,000。
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))
A number is called prime if it is only divisible by itself and 1. So iterate from 2 to n-1, if n is divisible by any of (2,3,4,..n-1) return False.如果一个数只能被自身和 1 整除,则该数称为素数。因此从 2 迭代到 n-1,如果 n 可被 (2,3,4,..n-1) 中的任何一个整除,则返回 False。
If j == n
then there is no such number from (2,3,4...n-1) divisible by n, Hence it's Prime.如果j == n
则 (2,3,4...n-1) 中没有这样的数可以被 n 整除,因此它是素数。
Since the goal is to print the number in case it's prime let's do that part first.由于目标是打印数字以防它是素数,让我们先做那部分。 You've already got a condition for it in your code but there was no print:您的代码中已经有了它的条件,但没有打印:
if a >= N:
print(N)
return
Next we need to handle all the cases where N > 1
:接下来我们需要处理所有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)
First check, if N == 2
is unnecessary since there's already a block before that handles all the cases where N
is prime so it can be removed.首先检查, if N == 2
是不必要的,因为在此之前已经有一个块处理所有N
为素数的情况,因此可以将其删除。 That said having it there doesn't cause any harm.也就是说,拥有它不会造成任何伤害。
The next block that checks if N
is divisible by a
should terminate the recursion.检查N
是否可被a
整除的下一个块应该终止递归。 Since you know that N
isn't prime you should just stop there.既然你知道N
不是素数,你就应该停在那里。
Final block that gets executed when N
is not divisible by a
should do the recursion instead.当N
不能被a
整除时执行的最终块应该执行递归。 As it stands now the recursion stops as soon as N % a != 0
which is clearly wrong.就目前而言,一旦N % a != 0
递归停止,这显然是错误的。
Here's a working sample with above modifications and cleanup:这是具有上述修改和清理的工作示例:
def is_prime(N, a=2):
if N <= 1:
return
elif a >= N:
print(N)
elif N % a != 0:
is_prime(N, a + 1)
to print the list of prime numbers between a given range打印给定范围之间的素数列表
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)
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)
if you don't want to use a helper function如果您不想使用辅助功能
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
Also, you don't need to check all the numbers between (1 - N) but only up to sqrt(n).此外,您不需要检查 (1 - N) 之间的所有数字,而只需要检查 sqrt(n)。 You can change your iterative approach to您可以将迭代方法更改为
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
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
Since there are so many cool attempts to improve the code, I gave it a try and here's my best solution to any case of finding if a number is prime using recursion.由于有很多很酷的尝试来改进代码,我试了一下,这是我使用递归查找数字是否为素数的最佳解决方案。 You'll have to add the print statements or any other logics yourself, but the main idea is quite simple:您必须自己添加打印语句或任何其他逻辑,但主要思想非常简单:
def is_prime_recursive(n, checkpoint = 2):
if n in [1, checkpoint]:
return True
if n % checkpoint == 0:
return False
return is_prime_recursive(n, checkpoint + 1)
This is repeated until the number falls into one of the cases - being the worst case the number is a prime: first case (n == checkpoint)重复此操作,直到数字落入其中一种情况 - 最坏的情况下,数字是素数:第一种情况(n == 检查点)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.