csq-python基础题解-素数
Python基础题解之素数
什么是素数?
素数(质数)是指在大于 1 的自然数中,除了 1 和它本身以外不再有其他因数的数。
例如:2, 3, 5, 7, 11, 13 ...
注意:
-1不是素数
- 最小的素数是2
一、基础判断法(单个素数判断)
1.1 试除法(最直观)
思路:对于数字 n,检查从 2 到 √n 的所有整数是否能整除 n。
import math
def is_prime_basic(n):
"""基础试除法判断素数"""
if n < 2:
return False
if n == 2:
return True
if n % 2 == 0:
return False
# 检查从 3 到 sqrt(n) 的奇数
limit = int(math.isqrt(n)) + 1
for i in range(3, limit, 2):
if n % i == 0:
return False
return True
# 测试
print(is_prime_basic(17)) # True
print(is_prime_basic(15)) # False
优化点:
排除偶数(除了 2)
只需检查到 √n(因数成对出现)
使用 math.isqrt() 避免浮点数误差
1.2 6k±1 优化法
数学原理:所有素数(除 2、3 外)都可表示为 6k ± 1 的形式。
def is_prime_optimized(n):
"""6k±1 优化法"""
if n <= 1:
return False
if n <= 3:
return True
if n % 2 == 0 or n % 3 == 0:
return False
# 检查 6k±1 形式的数
i = 5
while i * i <= n:
if n % i == 0 or n % (i + 2) == 0:
return False
i += 6
return True
优势:减少约 3/4 的检查次数
二、筛法求素数(批量生成)
2.1 埃拉托斯特尼筛法
核心思想:从 2 开始,标记每个素数的倍数为合数
def sieve_eratosthenes(n):
"""埃氏筛法求 ≤n 的所有素数"""
if n < 2:
return []
is_prime = [True] * (n + 1)
is_prime[0] = is_prime[1] = False
for i in range(2, int(n**0.5) + 1):
if is_prime[i]:
# 标记 i 的倍数为 False
for j in range(i*i, n+1, i):
is_prime[j] = False
primes = [i for i, prime in enumerate(is_prime) if prime]
return primes
# 示例:求 100 以内的素数
primes_100 = sieve_eratosthenes(100)
print(f"100以内素数数量: {len(primes_100)}")
print(f"前10个: {primes_100[:10]}")
2.2 欧拉筛法(线性筛)
优势:每个合数只被标记一次,时间复杂度 O(n)
def sieve_euler(n):
"""欧拉筛法(线性筛)"""
if n < 2:
return []
is_prime = [True] * (n + 1)
primes = []
for i in range(2, n + 1):
if is_prime[i]:
primes.append(i)
# 用已知素数筛除合数
for p in primes:
if i * p > n:
break
is_prime[i * p] = False
if i % p == 0: # 关键步骤:保证每个合数被最小质因数筛除
break
return primes
三、实用工具函数
3.1 素数分解(质因数分解)
def prime_factors(n):
"""返回 n 的质因数分解列表"""
factors = []
# 处理 2 的因子
while n % 2 == 0:
factors.append(2)
n //= 2
# 处理奇数因子
f = 3
while f * f <= n:
while n % f == 0:
factors.append(f)
n //= f
f += 2
if n > 1:
factors.append(n)
return factors
print(prime_factors(84)) # [2, 2, 3, 7]
四、性能对比与选择
| 方法 | 时间复杂度 | 空间复杂度 | 适用场景 |
|---|---|---|---|
| 试除法 | O(√n) |
O(1) |
判断少量大数 |
| 埃氏筛 | O(n log log n) |
O(n) |
中等范围素数生成 |
| 欧拉筛 | O(n) |
O(n) |
需要高效生成大量素数 |
💬 互动提问:你在Python开发中遇到过最棘手的素数问题是什么?欢迎评论区分享你的踩坑经历~
关于作者:Python初学小白
日期:2025/12/2
浙公网安备 33010602011771号