📜  Python 判断素数(1)

📅  最后修改于: 2023-12-03 15:34:10.481000             🧑  作者: Mango

Python 判断素数

素数(质数)是只能被1和自身整除的自然数,例如2、3、5、7、11等等。判断一个数是否是素数可以用以下方法:

方法一:暴力法

对于一个待判断的数n,在2到n-1之间依次判断是否整除n,若都不能整除,则n是素数。

def is_prime(n):
    if n <= 1:
        return False
    for i in range(2, n):
        if n % i == 0:
            return False
    return True

然而这种方法对于大数来说非常低效,需要遍历的数非常多。

方法二:优化暴力法

在方法一的基础上进行优化,只需要遍历到n的平方根即可。因为如果n不是素数,n一定可以分解为两个数的乘积:n=ab,那么a和b两个数中必有一个大于n的平方根,一个小于n的平方根。所以,如果在2到n的平方根之间找不到n的约数,那么n一定是素数。

import math

def is_prime(n):
    if n <= 1:
        return False
    for i in range(2, int(math.sqrt(n))+1):
        if n % i == 0:
            return False
    return True
方法三:Miller-Rabin算法

Miller-Rabin算法是一种随机化算法,可以用于判断一个数是否是素数。这种算法的正确性已经得到证明,但是其时间复杂度依然比较高。

import random

def is_prime(n, k=5):
    if n <= 1:
        return False
    elif n == 2 or n == 3:
        return True
    elif n % 2 == 0:
        return False
    
    d = n-1
    r = 0
    while d % 2 == 0:
        d //= 2
        r += 1
    
    for i in range(k):
        a = random.randint(2, n-2)
        x = pow(a, d, n)
        if x == 1 or x == n-1:
            continue
        for j in range(r-1):
            x = pow(x, 2, n)
            if x == n-1:
                break
        else:
            return False
    return True

这个算法的正确性基于两个事实:

  • 如果n是合数,则在2到n-1之间的任何一个数作为基数a都有很大的概率能够检测到n是合数;
  • 如果n是素数,则在2到n-1之间任意选择一个数作为基数a都能够验证出n是素数。