[英]How do I find a prime number using recursion in Python
我必須使用遞歸找出 number(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")
您的解決方案很接近,只需進行一些更改即可使其正常工作。
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
。
編輯:沒有意識到您希望該函數僅打印出素數,如果它是素數,則相應地更改了代碼。
你的函數有時會返回一些東西,有時什么也不返回——它應該是一個或另一個,而不是兩者。 在這種情況下is_prime()
看起來像一個布爾函數,所以它應該返回 True 或 False。 我們將打印留給調用者:
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)
把事情簡單化。 仔細考慮每一個可能的情況。 避免不必要地增加縮進深度,這會使您的代碼更加復雜。
上述解決方案試圖通過避免偶數(除數和數字)並將除數限制為數字的平方根來加速素數檢測。 這很重要,因為如果沒有這些優化,遞歸解決方案可能會在 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))
如果一個數只能被自身和 1 整除,則該數稱為素數。因此從 2 迭代到 n-1,如果 n 可被 (2,3,4,..n-1) 中的任何一個整除,則返回 False。
如果j == n
則 (2,3,4...n-1) 中沒有這樣的數可以被 n 整除,因此它是素數。
由於目標是打印數字以防它是素數,讓我們先做那部分。 您的代碼中已經有了它的條件,但沒有打印:
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)
打印給定范圍之間的素數列表
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)
如果您不想使用輔助功能
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)。 您可以將迭代方法更改為
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
由於有很多很酷的嘗試來改進代碼,我試了一下,這是我使用遞歸查找數字是否為素數的最佳解決方案。 您必須自己添加打印語句或任何其他邏輯,但主要思想非常簡單:
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)
重復此操作,直到數字落入其中一種情況 - 最壞的情況下,數字是素數:第一種情況(n == 檢查點)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.