CC++ & Algorithm

Python素数判断

困难4
语言版本:C++Python
概述:学习如何用Python判断一个数是不是素数,就像检查一个数字是否只有两个好朋友(1和它自己)。

让Python帮你找出素数

同学们,你们知道什么是素数吗?素数也叫质数,它就像班里一个特别“挑剔”的同学,只愿意和两个朋友玩——1和它自己。比如数字7,只能被1和7整除,所以7是素数。而数字6除了1和6,还能被2和3整除,朋友很多,所以6不是素数,而是合数。

在编程里,我们经常需要判断一个数是不是素数。比如做加密游戏、分配奖品时,都需要用到素数。今天我们就用Python来写一个“素数识别器”,让程序帮我们快速检查一个数字是不是素数。


什么是素数?用生活例子理解

假设你有8颗糖果,想分给一些同学,要求每个人分到的数量相同,而且不能有剩余。如果你分给1个人,他得到8颗;分给2个人,每人4颗;分给4个人,每人2颗;分给8个人,每人1颗。因为除了1和8之外,还能找到其他分法(2和4),所以8不是素数,它是合数。

但如果你有7颗糖果,除了分给1个人(得7颗)或分给7个人(每人1颗),再也找不到其他分法了。因此7是素数。

结论:一个数如果只能被1和它本身整除,它就是素数。注意,1比较特殊——它只能被1整除,但不符合“两个不同朋友”的条件(1和它自己是同一个数字),所以1不是素数。


如何用Python判断素数?——基础方法

核心思路很简单:从2开始检查,一直检查到这个数减1,看看有没有其他数字能整除它。如果都没有,它就是素数。

下面是一个基本的判断函数:

def is_prime(n):
    if n <= 1:          # 1不是素数,0和负数也不是
        return False
    for i in range(2, n):  # 从2到n-1逐个检查每个整数
        if n % i == 0:     # 如果n能被i整除
            return False   # 说明找到了第三个朋友,不是素数
    return True            # 没有找到其他朋友,是素数

# 测试几个数
print(is_prime(7))   # 输出 True
print(is_prime(10))  # 输出 False
print(is_prime(2))   # 输出 True(2是素数)

你可以把数字想象成班级里的一个同学。素数同学很孤独,只跟1和它自己玩。而合数同学朋友很多,除了1和自己,还有别的数字能跟它玩。通过循环检查,我们用Python帮每个数字数一数它的朋友数量,就知道它是不是素数了。

小提示:上面的代码虽然简单,但检查到n-1有点慢。比如判断一个大数1000000,要循环近100万次,很费时间。怎么优化呢?接着往下看。


优化方法:只检查到平方根

为什么可以只检查到平方根?
假设n不是素数,它有两个因子a和b,且a ≤ b。那么a一定小于等于√n(否则a × b > n)。所以只要检查从2到√n有没有能整除n的数,就足够了。如果到√n都没找到除数,那么√n之后也不会有。

比如判断100,√100=10。我们只需要检查210之间有没有数能整除100。2可以,所以100不是素数。如果检查到10还没找到,比如101,√101≈10.05,检查210都没有,101就是素数。

我们来写一个更快的版本:

import math

def is_prime_fast(n):
    if n <= 1:                    # 1和更小的数不是素数
        return False
    if n == 2:                    # 2是唯一的偶数素数
        return True
    if n % 2 == 0:                # 其他偶数都不可能是素数
        return False
    limit = int(math.sqrt(n))     # 计算平方根,并转为整数
    for i in range(3, limit + 1, 2):  # 只检查奇数,从3开始,步长为2
        if n % i == 0:            # 如果能被i整除
            return False          # 不是素数
    return True                   # 通过所有检查,是素数

# 测试
print(is_prime_fast(97))   # 输出 True
print(is_prime_fast(169))  # 输出 False(13×13=169)
print(is_prime_fast(2))    # 输出 True

这个优化版本不仅只检查到平方根,还跳过了所有偶数(因为除了2之外,偶数的质因数肯定是2,一开始就排除掉了),速度提升了很多。


常见错误(新手最容易犯)

  1. 忘记处理1和负数
    有些同学直接写 for i in range(2, n): 然后返回True,这样当n=1时,循环根本不会执行,直接返回True,但1不是素数。所以一定要先判断 n <= 1

  2. 循环范围写成 range(2, n+1)
    这样会检查到n本身,而任何数都能被自己整除,就会错误地返回False。记住检查到n-1就够了(或者到平方根)。

  3. 忘记考虑2是素数
    如果代码中先检查偶数并返回False,就会把2也判成合数。所以要先单独处理2。

  4. 取模运算 % 用成除法 /
    n % i 得到余数,判断余数是否为0;如果用 n / i 得到的是小数,不能直接判断整除。记住用 %


完整示例:让用户输入一个数并判断

下面是一个完整的程序,用户输入一个整数,程序告诉我们它是不是素数:

import math

def is_prime(n):
    """判断一个整数是不是素数,返回True或False"""
    if n <= 1:                     # 1、0和负数都不是素数
        return False
    if n == 2:                     # 2是素数
        return True
    if n % 2 == 0:                 # 其他偶数不是素数
        return False
    limit = int(math.sqrt(n))      # 取平方根的整数部分
    for i in range(3, limit + 1, 2):  # 从3到平方根,只检查奇数
        if n % i == 0:             # 如果能整除
            return False           # 不是素数
    return True                    # 是素数

# 主程序:用户输入,输出结果
user_num = int(input("请输入一个整数:"))   # 用户输入数字
if is_prime(user_num):
    print(f"{user_num} 是素数!")
else:
    print(f"{user_num} 不是素数。")

你可以运行这个程序,输入不同的数字测试一下。


相关知识点指引

学会了判断一个数是不是素数,你还可以继续探索:

  • 列出1到100的所有素数:用循环调用上面的函数,把素数收集到一个列表里。
  • 素数分解:把一个合数拆成几个素数的乘积,比如12=2×2×3。
  • 埃拉托色尼筛法:一种高效找出一定范围内所有素数的方法,比单个判断快很多。
  • 判断两个数是不是互质:如果两个数的最大公约数是1,它们就是互质数(比如8和9)。

继续加油,用Python探索更多数学的乐趣吧!

例题精讲

1单选题

以下哪个选项中的数不是素数?

A2
B3
C4
D5
2单选题

在判断一个大于1的自然数n是否为素数时,最优化方法中循环的上界通常设置为( )。

An-1
Bn//2
Cint(n**0.5)
Dn
3判断题

数字1是素数。

4填空题
以下函数用于判断正整数n是否为素数,请在空白处填写正确的表达式。

def is_prime(n):
    if n <= 1:
        return False
    for i in range(2, ___):
        if n % i == 0:
            return False
    return True
5填空题
下面程序的功能是输出100以内的所有素数,请在空白处填写正确的条件。

for num in range(2, 101):
    prime = True
    for i in range(2, int(num**0.5)+1):
        if ___:
            prime = False
            break
    if prime:
        print(num)