Python 练习讲解 · 23 / 25

整除、因数、倍数与同余

整除看余数是否为 0;同余则比较两个数除以同一数后的余数。

要学习的知识点

题目

补充练习:整除、因数、倍数、取余与同余。

输入:正整数 d、整数 n、正整数 m。判断 d 是否整除 n,列出 d 的因数及前五个正倍数,

并判断 d 与 n 是否模 m 同余。

参考程序:ex23.py;空白练习:lx23.py。

完整代码

以下内容与 ex23.py 一致,可对照右侧讲解阅读。

"""补充练习:整除、因数、倍数、取余与同余。
输入:正整数 d、整数 n、正整数 m。判断 d 是否整除 n,列出 d 的因数及前五个正倍数,
并判断 d 与 n 是否模 m 同余。

学习说明:
- 若 n % d == 0,表示 d 整除 n;否则不能整除。
- 因数是能整除 d 的正整数,所以只需检查 1 到 d。
- d * k(k 为正整数)是 d 的倍数;本题列出前五个。
- n % m 是余数;两个数对 m 同余,等价于它们余数相同。
- 列表解析把满足条件的因数收集成一个列表。
"""
d, n, m = map(int, input().split())
if d <= 0 or m <= 0:
    raise ValueError("d 和 m 必须为正整数")

print("divisible:", n % d == 0)
factors = [value for value in range(1, d + 1) if d % value == 0]
print("factors:", *factors)
print("first five multiples:", *(d * k for k in range(1, 6)))
print("remainder:", n % m)
print("congruent:", d % m == n % m)

进阶写法

这版与初学版解决同一道题,使用更精炼的语法或标准库工具。

进阶源码:ex23_adv.py

"""练习 23 进阶版:用列表解析和生成器表达式列出因数与倍数。"""
d, n, m = map(int, input().split())
if d <= 0 or m <= 0:
    raise ValueError("d 和 m 必须为正整数")

factors = [value for value in range(1, d + 1) if d % value == 0]
print("divisible:", n % d == 0)
print("factors:", *factors)
print("first five multiples:", *(d * k for k in range(1, 6)))
print("remainder:", n % m)
print("congruent:", d % m == n % m)

列表解析一次筛出所有因数;生成器表达式即时产生前五个倍数,星号将它们作为多个 print 参数。

运行结果

示例输入:

6 18 4

程序输出:

divisible: True
factors: 1 2 3 6
first five multiples: 6 12 18 24 30
remainder: 2
congruent: True

逐个认识函数

下表根据程序中实际调用的函数和方法整理;自定义函数的实现与算法细节见后续说明。

函数形式功能与返回值注意事项
ValueError(message)内置异常类型,用来表示参数值不符合要求。raise ValueError(...) 会立即抛错并停止当前程序流程。
input(prompt='')读取一行文本,返回 str;若提供 prompt 会先显示提示。返回值默认是字符串,计算前通常要做类型转换。
str.split(sep=None)按分隔符拆分字符串,返回字符串列表。默认按连续空白拆分并忽略首尾空白。
map(function, iterable)逐个应用函数,返回惰性迭代器。常与 list() 一起使用以立即取得结果。
print(*objects, sep=' ', end='\n')把对象转换为文本显示;返回 None。默认空格分隔并在末尾换行。
range(start, stop, step=1)产生整数序列供循环或索引使用。stop 不包含在序列里。

数学概念变成程序判断

  • 整除:d 整除 n 等价于 n % d == 0。条件成立时没有余数。
  • 因数:若 d 除以 value 的余数为 0,value 就是 d 的正因数。程序检查 1 到 d。
  • 倍数:d、2d、3d...;第 k 个正倍数是 d*k。
  • 取余:n % m 求除法余数;m 为正时余数在 0 到 m-1 之间。
  • 同余:d ≡ n (mod m) 当且仅当 d % m == n % m。

函数、解析式和解包

写法参数 / 返回值题中的作用
input().split()读入一行文本并按空白拆分。输入 d、n、m 三个文本。
map(int, ...)对可迭代内容逐个调用 int,返回 map 对象。多重赋值将三个转换结果分别存入 d、n、m。
range(1, d + 1)产生 1 到 d 的整数序列,末尾不含 d+1。遍历所有候选正因数。
[value for ... if ...]列表解析,返回符合条件的新列表。把所有整除 d 的候选数字留下来。
*(generator)星号解包可迭代对象,作为多个函数参数。为避免先存倍数列表,程序直接把生成器中的 5 个倍数解包给 print。
print(...)显示参数;默认空格分隔。输出判断结果、因数列表和倍数。

边界和验证

d 和 m 必须大于 0:d 是除数,m 是模数。n 可以是负数,Python 对正除数也定义了取余,因此整除和同余仍可判断。请试 d=1、n=0、n 为负数,以及 m=1。

比如 14 和 26 对 4 同余,因为它们余数都为 2;它们本身不相等也没关系。

代码如何运行

  1. 先按左侧题目给出的格式输入数据;程序通过 input() 读取,并在需要时转换数据类型。
  2. 程序自上而下执行语句;遇到条件、循环或函数调用时,按照右侧算法说明更新变量和处理数据。
  3. 最后由 print() 输出计算结果。可将左侧示例输入与输出逐项对照。

先自己跟踪一组小数据,记录循环前后变量的值;这比只看最终答案更容易理解程序。

自己动手试一试

测试 d=1、n=0、负数 n 和 m=1;用不同余数验证同余判断。

先在 lx23.py 中独立完成,再运行参考程序比较结果。修改程序时一次只改一个条件或步骤。