简体   繁体   English

质数递归 - 它是如何工作的? (蟒蛇)

[英]Prime Number Recursion- How Does It Work? (Python)

I was wondering how this program knows if a number is prime or not.我想知道这个程序如何知道一个数字是否为素数。 I understand that it checks for remainders to find even numbers to divide by but how does it know that a number has only 2 factors?我知道它会检查余数以找到要除以的偶数,但它如何知道一个数字只有 2 个因数? I'm new to the concept of recursion so a explanation of the steps would be helpful thank you.我是递归概念的新手,因此对步骤的解释会有所帮助,谢谢。

Code代码

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)

Source来源

https://github.com/hydrogeologist/LearningPython/blob/master/_recursion%20example%20in%20Python https://github.com/hydrogeologist/LearningPython/blob/master/_recursion%20example%20in%20Python

Lines: 184 to 194线路:184 至 194

It checks whether there's any number from m - 1 down to 1 that divides m, it doesn't check just even numbers.它检查是否有任何从 m - 1 到 1 的数除以 m,它不只检查偶数。

EG, for RecIsPrime(10) you will have these nested functions call:例如,对于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 is false , so the right hand side of the and won't be evaulated. 10 % 5 != 0false ,因此不会对and的右侧进行评估。 PrimeHelper(10, 5) will return false and doesn't continue the recursion. PrimeHelper(10, 5)将返回false并且不继续递归。
In PrimeHelper(10, 6) you get 10 % 6 != 0 to be true , but we've just seen PrimeHelper(10, 5) to be false so this will return false as well, and so will all the other calls.PrimeHelper(10, 6)您得到10 % 6 != 0true ,但我们刚刚看到PrimeHelper(10, 5)false因此这也将返回假,所有其他调用也是如此。

This code is a tail recursion case, ie it can be seen as a recursive way to perform iteration.这段代码是一个尾递归的情况,即它可以被看作是一种执行迭代的递归方式。 Note that Python doesn't actually interpret it that way (which would be an optimisation), but it is still helpful to see it like that:请注意,Python 实际上并没有那样解释它(这将是一种优化),但是这样看仍然很有帮助:

See how every recursive call of PrimeHelper has the same value for m , but has a value for j that is one less compared to the value it had in the previous call.看看PrimeHelper每个递归调用如何具有相同的m值,但其j的值与它在前一次调用中的值相比小一。

So the code is comparable to this variant:因此该代码可与此变体相媲美:

def RecIsPrime(m):
    for j in range(m-1, 1, -1):
        if m % j == 0:
            return False
    return m > 1

In this variant every iteration corresponds to a recursive call in the original code.在这个变体中,每次迭代都对应于原始代码中的递归调用。 Note that return False breaks the chain, which is done by m % j != 0 in the original code, ie there it serves two purposes:请注意, return False打破了链,这是由原始代码中的m % j != 0完成的,即它有两个目的:

  1. Return False返回False
  2. Don't call PrimeHelper anymore不要再调用PrimeHelper

It is important to note that the two variants do not behave the same way when you call RecIsPrime with an argument of 1 or less.请务必注意,当您使用 1 或更小的参数调用RecIsPrime时,这两个变体的行为方式不同。 In those cases the recursive code can produce a "division by zero" error (when RecIsPrime(1) ) or recurse for ever (eg RecIsPrime(-1) or any lesser value).在这些情况下,递归代码可能会产生“被零除”错误(当RecIsPrime(1) )或永远递归(例如RecIsPrime(-1)或任何较小的值)。 This is a bug.这是一个错误。 To correct it change:要纠正它更改:

return PrimeHelper(m, m -1)

by

return m > 1 and PrimeHelper(m, m -1)

which also fixes the case for 1: it is more than just "debatable" whether 1 is prime or not: it is definitely not.这也解决了 1 的情况:1 是否是质数不仅仅是“有争议的” :它绝对不是。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM