第 07 章 程序设计方法
学习目标
- 理解过程式、函数式和生态式编程。
- 用自顶向下的方法拆分问题。
- 使用蒙特卡洛方法估计随机问题。
- 使用递归表达可以分解的计算问题。
1. IPO 方法
程序可以分成输入 Input、处理 Process 和输出 Output。例如,输入长和宽,处理面积公式,输出面积。先确定输入输出,再设计处理步骤。
2. 过程式编程
过程式编程按照解决问题的步骤编写语句:
total = 0
for score in [88, 92, 76]:
total += score
print(total / 3)
它强调顺序、分支和循环,适合步骤清楚的问题。
3. 函数式编程
函数式编程把问题拆成若干功能明确的函数:
def total(values):
result = 0
for value in values:
result += value
return result
def average(values):
return total(values) / len(values)
print(average([88, 92, 76]))
每个函数只承担一种功能,主程序负责组合这些函数。
4. 自顶向下
估算班级成绩时,可以先写成:
scores = read_scores()
result = average(scores)
show_result(result)
然后再分别实现读取、计算和显示。先写整体流程,再实现每个部分,这就是自顶向下设计。
5. 生态式编程
生态式编程直接使用成熟的标准库或第三方库。例如,随机数使用 random,绘图使用 turtle,中文分词使用 jieba。库能够可靠完成任务时,不必从零编写全部代码。
6. 蒙特卡洛方法
蒙特卡洛方法通过大量随机试验估计结果。单位正方形中随机投点,点到原点距离不超过 1 的比例,可用来估计四分之一圆面积:
import random
times = 10000
inside = 0
for i in range(times):
x = random.random()
y = random.random()
if x * x + y * y <= 1:
inside += 1
print(4 * inside / times)
随机次数越多,结果通常越接近圆周率,但每次结果不一定完全相同。
7. 递归计算方法
递归把问题分成相同形式、规模更小的问题。计算阶乘时,n! = n * (n - 1)!,而 1! = 1:
def factorial(n):
if n == 1:
return 1
return n * factorial(n - 1)
必须先写停止条件,否则递归不会结束。
本章练习
- 用 IPO 描述温度转换程序的输入、处理和输出。
- 把平均分计算拆成两个函数。
- 用 1000 次随机试验估计掷骰子得到 6 点的比例。
- 用递归计算 1 到 n 的和。
本章小结
- 过程式强调步骤,函数式强调功能拆分,生态式强调使用现有库。
- 自顶向下先设计总体,再实现细节。
- 蒙特卡洛方法用大量随机试验估计结果。
- 递归方法需要基例和规模递减的递归关系。