质数是指只能被1和自己整除的正整数,例如2、3、5、7、11、13等等。判断一个数是否为质数是数学中的基本问题之一,本文将介绍多种方法来判断一个数是否为质数。
一、试除法
试除法是最基本的一种方法,其思路是尝试用2到该数的平方根的所有整数去除该数,如果都不能整除,那么该数就是质数。相反,如果有一个数可以整除该数,那么该数就不是质数。
def is_prime(n):
if n <= 1:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
对于传入的n,首先判断其是否小于等于1,因为1不是质数。然后用一个循环从2到n的平方根来逐个判断是否可以整除n,如果可以整除,那么n就不是质数,直接返回False;否则n就是质数,返回True。
二、埃氏筛法
埃氏筛法是一种非常高效的筛选质数的方法,它的思路是从2开始,将所有能被2整除的数标记为合数,然后再以3为起点,将所有能被3整除的数标记为合数。不断重复这个过程,就能将小于等于n的质数全部筛选出来。
def eratosthenes(n):
if n <= 1:
return []
nums = [i for i in range(2, n+1)]
i = 0
while i < len(nums):
p = nums[i]
nums = nums[:i+1] + [x for x in nums[i+1:] if x % p != 0]
i += 1
if i >= len(nums):
break
return nums
对于传入的n,首先判断其是否小于等于1,因为1不是质数。然后初始化一个数组nums,用于存储2到n的所有整数。接着用一个循环,依次取出数组中的每个质数p,然后将所有能被p整除的数从数组中删除,最后返回剩下的数组即为所有小于等于n的质数。
三、费马小定理
费马小定理是一种用于判断质数的数论定理,其核心思想是通过快速幂来进行模运算,从而判断一个数是否为质数。
def is_prime_fermat(n, k=5):
if n <= 1:
return False
if n == 2 or n == 3:
return True
for i in range(k):
a = random.randint(2, n - 2)
if pow(a, n - 1, n) != 1:
return False
return True
对于传入的n,首先判断其是否小于等于1,因为1不是质数。然后判断n是否等于2或3,如果是,则n为质数。接着进行k次随机测试,每次随机选择一个2到n-2之间的整数a,判断是否满足a^(n-1) ≡ 1 (mod n),如果所有的测试都通过了,那么n就可能是质数,返回True。注意,这里的k表示进行测试的次数,k越大,误判为质数的概率就越小。
四、米勒-拉宾素数检验
米勒-拉宾素数检验是一种基于费马小定理进行改进的算法,其思路是先将n-1分解成2^s * t的形式,然后随机选择一个2到n-2之间的整数a,计算a^t mod n的值,如果等于1或n-1,那么n可能是质数。否则,不断将a^t mod n进行平方运算,并检查结果是否等于n-1。如果能够通过k次测试,那么就认为n是质数。
def miller_rabin(n, k=5):
if n <= 1:
return False
if n == 2 or n == 3:
return True
if n % 2 == 0:
return False
s = 0
t = n - 1
while t % 2 == 0:
t //= 2
s += 1
for i in range(k):
a = random.randint(2, n - 2)
x = pow(a, t, n)
if x == 1 or x == n - 1:
continue
for j in range(s - 1):
x = pow(x, 2, n)
if x == n - 1:
break
else:
return False
return True
对于传入的n,首先判断其是否小于等于1,因为1不是质数。然后判断n是否等于2或3,如果是,则n为质数。接着判断n是否为偶数,如果是,则n不是质数。然后将n-1分解成2^s * t的形式,其中t是奇数,s是非负整数。接着进行k次随机测试,每次随机选择一个2到n-2之间的整数a,计算a^t mod n的值,如果等于1或n-1,那么继续下一轮循环。否则,不断将a^t mod n进行平方运算,并检查是否等于n-1。如果k次测试都通过了,那么n可能是质数,返回True。