csq17

导航

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

posted on 2025-12-02 23:13  陈诗棋  阅读(6)  评论(0)    收藏  举报