要学习的知识点
- 算法的输入、输出与确定步骤
- 算法有限性
- 循环累加
- 等差数列求和公式
- 时间复杂度 O(n) 与 O(1)
题目
补充练习:理解算法的输入、确定步骤、有限性和输出。
输入非负整数 n;分别用循环算法和公式算法计算 1+...+n,并比较结果与操作次数。
完整代码
以下内容与 ex25.py 一致,可对照右侧讲解阅读。
"""补充练习:理解算法的输入、确定步骤、有限性和输出。
输入非负整数 n;分别用循环算法和公式算法计算 1+...+n,并比较结果与操作次数。
学习说明:
- 输入是 n,输出是从 1 到 n 的整数和;n=0 时总和为 0。
- 循环算法的步骤明确,每次累加一个数;循环次数有限,为 n 次。
- 公式算法使用 n*(n+1)//2,运算步骤数不随 n 增长。
- 两种算法计算同一结果,比较它们可以帮助理解算法设计和效率。
"""
n = int(input())
if n < 0:
raise ValueError("n 必须为非负整数")
# 循环算法:步骤明确,每次将下一个整数加入总和,执行有限次。
loop_total = 0
for value in range(1, n + 1):
loop_total += value
# 公式算法:使用等差数列求和公式,常数次算术运算得到结果。
formula_total = n * (n + 1) // 2
print("loop result and additions:", loop_total, n)
print("formula result:", formula_total)
print("results match:", loop_total == formula_total)
进阶写法
这版与初学版解决同一道题,使用更精炼的语法或标准库工具。
进阶源码:ex25_adv.py
"""练习 25 进阶版:用 sum 和 range 计算循环累加结果。"""
n = int(input())
if n < 0:
raise ValueError("n 必须为非负整数")
loop_total = sum(range(1, n + 1))
formula_total = n * (n + 1) // 2
print("loop result and additions:", loop_total, n)
print("formula result:", formula_total)
print("results match:", loop_total == formula_total)
sum(range(1, n+1)) 用内置求和计算循环累加结果,range() 提供 1 到 n;公式部分用固定次算术运算计算。
运行结果
示例输入:
10程序输出:
loop result and additions: 55 10
formula result: 55
results match: True逐个认识函数
下表根据程序中实际调用的函数和方法整理;自定义函数的实现与算法细节见后续说明。
| 函数形式 | 功能与返回值 | 注意事项 |
|---|---|---|
ValueError(message) | 内置异常类型,用来表示参数值不符合要求。 | raise ValueError(...) 会立即抛错并停止当前程序流程。 |
input(prompt='') | 读取一行文本,返回 str;若提供 prompt 会先显示提示。 | 返回值默认是字符串,计算前通常要做类型转换。 |
int(value, base=10) | 把整数文本或数值转换为整数。 | int('3.5') 不合法;按指定进制解析时可传 base。 |
print(*objects, sep=' ', end='\n') | 把对象转换为文本显示;返回 None。 | 默认空格分隔并在末尾换行。 |
range(start, stop, step=1) | 产生整数序列供循环或索引使用。 | stop 不包含在序列里。 |
算法的几个特点
- 有输入:本题输入 n。
- 有输出:本题输出总和以及两种结果是否相同。
- 步骤明确:循环每次把当前整数加到总和;公式明确是 n(n+1)/2。
- 有限性:循环从 1 到 n,有限次后结束。
- 有效性:对题目允许的输入,步骤能得到正确结果。
两种算法如何运行
循环累加
loop_total = 0
for value in range(1, n + 1):
loop_total += value初始总和是 0。n=4 时依次变为 1、3、6、10。循环次数是 n,时间量级 O(n)。
等差数列公式
formula_total = n * (n + 1) // 2把首尾配对:1+n、2+(n-1),每对都等于 n+1。所有数的总和是 n(n+1)/2。该写法用固定次数的算术运算,时间量级 O(1)。整数除法 // 可确保得到整数。
代码中的函数和运算
| 函数/写法 | 参数与返回值 | 说明 |
|---|---|---|
input() | 读入一行,返回字符串。 | 与 int 配合得到 n。 |
int(text) | 把整数文本转换为 int。 | 输入非整数文本会产生 ValueError。 |
range(1, n + 1) | 生成整数序列 1 到 n。 | 停止位置不包含在序列中,因此写 n+1。 |
+= | 累加赋值,更新变量本身。 | loop_total += value 等价于总和加上 value 后再保存。 |
== | 比较是否相等,返回 bool。 | 检查两种算法结果一致;它不是赋值号。 |
print(...) | 向终端输出数据,返回 None。 | 显示中间结果、公式结果和比较结果。 |
效率不只看代码行数
当 n 很小时,两种方法都够快;n 很大时,循环要执行 n 次,公式依旧只做几步。算法分析关心输入规模变大时工作量如何变化,而不只是程序写了几行。
循环累加能帮助理解过程,公式法更快但需要证明正确。竞赛中既要能实现算法,也要理解为什么它得到正确答案。
尝试把循环次数也输出。再为 n=0、n=1、n=1000 测试,并解释每个结果。
代码如何运行
- 先按左侧题目给出的格式输入数据;程序通过 input() 读取,并在需要时转换数据类型。
- 程序自上而下执行语句;遇到条件、循环或函数调用时,按照右侧算法说明更新变量和处理数据。
- 最后由 print() 输出计算结果。可将左侧示例输入与输出逐项对照。
先自己跟踪一组小数据,记录循环前后变量的值;这比只看最终答案更容易理解程序。
自己动手试一试
测试 n=0、1 和较大的数;比较循环次数,并解释公式为什么不随 n 循环。
先在 lx25.py 中独立完成,再运行参考程序比较结果。修改程序时一次只改一个条件或步骤。