我想知道这个程序是如何知道数字是否为素数。我知道它会检查余数以找到偶数除以但是它如何知道数字只有2个因子?我是递归概念的新手,所以对步骤的解释会有所帮助,谢谢。
代码
def RecIsPrime(m):
"""Uses recursion to check if m is prime."""
def PrimeHelper(m, j):
"""Helper Function to iterate through all j less than m up to 1 to look for even divisors."""
if j == 1: # Assume 1 is a prime number even though it's debatable.
return True
else:
#do this task if both conditionals are true
#else break and return false.
return m % j != 0 and PrimeHelper(m, j - 1)
return PrimeHelper(m, m -1)
来源
https://github.com/hydrogeologist/LearningPython/blob/master/_recursion%20example%20in%20Python
行:184到194
答案 0 :(得分:2)
检查是否存在从m - 1到1除以m的任何数字,它不会检查偶数。
EG,对于RecIsPrime(10)
,您将拥有这些嵌套函数调用:
PrimeHelper(10, 9) = 10 % 9 != 0 and PrimeHelper(10, 8)
↪ PrimeHelper(10, 8) = 10 % 8 != 0 and PrimeHelper(10, 7)
↪ PrimeHelper(10, 7) = 10 % 7 != 0 and PrimeHelper(10, 6)
↪ PrimeHelper(10, 6) = 10 % 6 != 0 and PrimeHelper(10, 5)
↪ PrimeHelper(10, 5) = 10 % 5 != 0 == false
10 % 5 != 0
为false
,因此and
的右侧不会被评估。 PrimeHelper(10, 5)
将返回false
并且不会继续递归
在PrimeHelper(10, 6)
中,您10 % 6 != 0
为true
,但我们刚看到PrimeHelper(10, 5)
为false
,所以这也将返回false,并且所有其他电话也是如此。
答案 1 :(得分:0)
此代码是尾递归的情况,即它可以被视为执行迭代的递归方式。请注意,Python实际上并没有那样解释它(这将是一种优化),但它仍然有助于看到它:
查看PrimeHelper
的每个递归调用对 m 的值是否相同,但 j 的值与值相比减少了一个在之前的电话会议中。
因此代码与此变体相当:
def RecIsPrime(m):
for j in range(m-1, 1, -1):
if m % j == 0:
return False
return m > 1
在此变体中,每次迭代都对应于原始代码中的递归调用。请注意return False
打破了链,这是由原始代码中的m % j != 0
完成的,即它有两个目的:
False
PrimeHelper
值得注意的是,当您使用1或更小的参数调用RecIsPrime
时,这两种变体的行为方式不同。在这些情况下,递归代码可以产生"除以零" 错误(当RecIsPrime(1)
时)或递归(例如RecIsPrime(-1)
或更低的值) )。这是一个错误。要纠正它的变化:
return PrimeHelper(m, m -1)
通过
return m > 1 and PrimeHelper(m, m -1)
还修复了1的情况:它不仅仅是"有争议的" 1是否为素数:它绝对不是。