How do I find a prime number using recursion in Python

前端 未结 6 1573
Happy的楠姐
Happy的楠姐 2020-12-21 13:26

I have to find out whether number(N) is a prime or not using recursion, no loops are allowed. I\'ve tried converting the usual code that uses a for loop to a recursive one,

相关标签:
6条回答
  • 2020-12-21 13:35

    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)
    
    0 讨论(0)
  • 2020-12-21 13:40

    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. 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.

    0 讨论(0)
  • 2020-12-21 13:42
    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.
    If j == n then there is no such number from (2,3,4...n-1) divisible by n, Hence it's Prime.

    0 讨论(0)
  • 2020-12-21 13:48

    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. 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. Maybe your confusion comes from a misunderstanding of scopes in Python. That prime variable will not be 'shared' across invocations, it will just create a new prime every time.

    EDIT: Didn't realize you wanted the function to just print out the prime if it's a prime, changed the code accordingly.

    0 讨论(0)
  • 2020-12-21 13:49
    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). You can change your iterative approach to

    for loop

    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 loop

    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
    
    0 讨论(0)
  • 2020-12-21 14:02

    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:

    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. 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. Since you know that N isn't prime you should just stop there.

    Final block that gets executed when N is not divisible by a should do the recursion instead. As it stands now the recursion stops as soon as N % a != 0 which is clearly wrong.

    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)
    
    0 讨论(0)
提交回复
热议问题