跳到主要内容

算法设计与问题求解

IGCSE 计算机科学 · 知识点 7

本主题的视频课程 打开视频页面
9:17

程序开发生命周期

你手机上的每一个应用都是由像这样的人编写的。但他们并非从敲下代码开始。在第一行代码之前,问题被研究,解决方案被设计……

英语旁白 · 英中内嵌字幕

教学大纲
考生应能够: 说明与指导
1 理解程序开发生命周期,仅限于:分析、设计、编码和测试 • 包括识别每个阶段并为每个阶段执行以下任务: – 分析:抽象化、问题分解、识别问题和需求 – 设计:分解、结构图、流程图、伪代码 – 编码:编写程序代码并进行迭代测试 – 测试:使用测试数据对程序代码进行测试
2 (a) 理解每个计算机系统由子系统组成,而子系统又由更小的子系统组成 (b) 理解如何将问题分解为其组成部分 • 包括: – 输入 – 处理 – 输出 – 存储
(c) 使用不同的方法来设计和构建问题的解决方案 • 包括: – 结构图 – 流程图 – 伪代码
3 解释给定算法的目的 • 包括: – 陈述算法的目的 – 描述算法中涉及的处理过程
4 理解标准求解方法 • 仅限于: – 线性搜索 – 冒泡排序 – 求和 – 计数 – 查找最大值、最小值和平均值
5 (a) 理解需要对输入数据进行验证检查以及不同类型的验证检查 • 包括: – 范围检查 – 长度检查 – 类型检查 – 存在性检查 – 格式检查 – 校验位
(b) 理解需要对输入数据进行核实检查以及不同类型的核实检查 • 包括: – 视觉检查 – 双重录入检查
6 建议并应用适当的测试数据 • 仅限于: – 正常数据 – 异常数据 – 极值数据 – 边界数据 • 极值数据是可接受的最大/最小值 • 边界数据是可接受的最大/最小值以及对应的被拒绝的最小/最大值
7 完成跟踪表以记录算法的干运行 • 包括在算法的每一步: – 变量 – 输出 – 用户提示
8 识别给定算法中的错误并提出纠正这些错误的方法
9 使用伪代码、程序代码和流程图编写和修改给定问题或场景的算法 • 编写算法时需要精确,例如 x > y 是可接受的,但 x is greater than y 是不可接受的 • 参见第4节关于流程图符号 • 参见第4节关于伪代码

来源:Cambridge International 教学大纲

7.1

程序开发生命周期

程序开发生命周期(program development life cycle)是用来制作一个程序的一套阶段。有四个阶段。

一个程序员在一台计算机前键入代码
软件由程序员编写,他们遵循开发生命周期
阶段 你做什么
分析(analysis) 研究问题并算出需要什么
设计(design) 规划程序将如何工作
编码(coding) 编写程序代码并随手测试它
测试(testing) 用测试数据运行完成的程序以找到错误
一排四个阶段——分析、设计、编码、测试——一个箭头从测试反馈到设计
程序开发的四个阶段;测试反馈以修复和精炼设计
一个带处理框和判断菱形的程序流程图
一个程序流程图在设计阶段布置一个程序的步骤和判断

分析

在分析中你理解问题。两个关键技能有帮助:

  • 抽象(abstraction)——只保留重要的细节并忽略其余的;
  • 分解(decomposition)——把一个大问题分成更小、更容易的部分。

设计

在设计中你规划解决方案,常常用分解。你可以把各部分显示为一个结构图(structure diagram,一个把一个系统分成更小的框的图)中的子系统(sub-systems)。

编码与测试

在编码中你编写程序代码。你用迭代测试(iterative testing)——在你构建小部分时一遍又一遍地测试它们。在测试中你用测试数据(test data)运行整个程序以检查它工作。

词汇 训练
English 中文 拼音
program development life cycle/ˈprəʊɡræm dɪˈveləpmənt laɪf ˈsaɪkl/ 程序开发生命周期 chéng xù kāi fā shēng mìng zhōu qī
analysis/əˈnæləsɪs/ 分析 fēn xī
design/dɪˈzaɪn/ 设计 shè jì
coding/ˈkəʊdɪŋ/ 编码 biān mǎ
testing/ˈtestɪŋ/ 测试 cè shì
abstraction/əbˈstrækʃn/ 抽象 chōu xiàng
decomposition/ˌdiːkɒmpəˈzɪʃn/ 分解 fēn jiě
sub-systems/sʌb ˈsɪstəmz/ 子系统 zǐ xì tǒng
structure diagram/ˈstrʌktʃə ˈdaɪəɡræm/ 结构图 jié gòu tú
iterative testing/ˈɪtərətɪv ˈtestɪŋ/ 迭代测试 dié dài cè shì
test data/test ˈdeɪtə/ 测试数据 cè shì shù jù
flowchart/ˈfləʊtʃɑːt/ 流程图 liú chéng tú
7.2

设计工具

你可以用三种主要方式规划一个解决方案。

  • 一个结构图(structure diagram)——显示一个系统的各部分以及它们如何组合在一起;
  • 一个流程图(flowchart)——一个用框和箭头按顺序显示步骤的图;
  • 伪代码(pseudocode)——用简单的、类似代码的英语书写的步骤(不是一门真实的语言)。
一个把数字 1 加到 n 的流程图,带开始/结束、输入/输出、处理和判断符号,加上一个命名每个形状的图例
求和算法的一个流程图,用标准符号(开始/结束、输入/输出、处理、判断)
词汇 训练
English 中文 拼音
pseudocode/ˈsuːdəʊkəʊd/ 伪代码 wěi dài mǎ
7.3

算法

冒泡排序,一趟接一趟

一个算法(algorithm)是解决一个问题的一套步骤,以正确的顺序。每个算法能被分成三部分:

  • 输入(input)——进去的数据;
  • 处理(processing)——对数据做的工作;
  • 输出(output)——出来的结果。

这叫分解成输入、处理和输出。例如,对于"求三个分数的平均值":输入是三个分数;处理是把它们相加并除以 3;输出是平均值。

三个框——INPUT(3 个分数)、PROCESS(把它们相加,除以 3)、OUTPUT(平均值)——由箭头连接
每个算法分解成输入、处理和输出——这里,求三个分数的平均值
词汇 训练
English 中文 拼音
algorithm/ˈælɡərɪθəm/ 算法 suàn fǎ
input/ˈɪnpʊt/ 输入 shū rù
processing/ˈprəʊsesɪŋ/ 处理 chǔ lǐ
output/ˈaʊtpʊt/ 输出 shū chū
bubble sort/ˈbʌbl sɔːt/ 冒泡排序 mào pào pái xù
totalling/ˈtəʊtəlɪŋ/ 求和 qiú hé
counting/ˈkaʊntɪŋ/ 计数 jì shù
7.4

有效性检查与准确性检查

当数据被输入时,你检查它以减少错误。

验证(validation)检查数据是合理的并遵循规则。它不能检查数据是真的,只能检查它是被允许的。

验证检查 它检查什么
范围检查(range check) 值在一个最低和最高允许值之间
长度检查(length check) 字符的数目被允许(例如一个密码 ≥ 8)
类型检查(type check) 数据是正确的类型(例如一个数,而不是字母)
存在性检查(presence check) 某样东西实际被输入(没有留空)
格式检查(format check) 数据在正确的模式中(例如一个日期作为 dd/mm/yyyy)
校验码 一个额外计算的数字,用于在输入数字时检测错误

核实(verification)检查数据被正确地复制或输入(键入它时没有错误)。两种方法:

  • 目视检查(visual check)——一个人把键入的数据与原始比较;
  • 双重输入(double entry)——数据被输入两次,而两个副本被比较。
词汇 训练
English 中文 拼音
validation/ˌvælɪˈdeɪʃn/ 验证 yàn zhèng
range check/reɪndʒ tʃek/ 范围检查 fàn wéi jiǎn chá
length check/leŋθ tʃek/ 长度检查 cháng dù jiǎn chá
type check/taɪp tʃek/ 类型检查 lèi xíng jiǎn chá
presence check/ˈprezəns tʃek/ 存在性检查 cún zài xìng jiǎn chá
format check/ˈfɔːmæt tʃek/ 格式检查 gé shì jiǎn chá
check digit/tʃek ˈdɪdʒɪt/ 校验码 jiào yàn mǎ
verification/ˌverɪfɪˈkeɪʃn/ 核实 hé shí
visual check/ˈvɪʒuːəl tʃek/ 目视检查 mù shì jiǎn chá
double entry/ˈdʌbl ˈentri/ 双重输入 shuāng chóng shū rù
7.5

跟踪表

一个追踪表(trace table)一步步地记录一个算法运行时每个变量的值。它帮助你:

一个追踪表,带列 count、total、output
一个追踪表在程序运行时记录每个变量的值
  • 检查一个算法正确地工作;
  • 通过用给定的数据跟随它来算出一个算法做什么。

例子:用输入 5 追踪这个算法。

INPUT N
Total ← 0
FOR I ← 1 TO N
    Total ← Total + I
NEXT I
OUTPUT Total
i total OUTPUT
1 1
2 3
3 6
4 10
5 15 15

追踪显示算法把 1 到 n 相加。用输入 5,输出是 15。

例题。 追踪这个算法并给出输出。

X ← 20
Count ← 0
WHILE X > 1
    X ← DIV(X, 2)
    Count ← Count + 1
ENDWHILE
OUTPUT Count

DIV 只取除法的整数部分。每循环一次写一行:x 变成 10(count 为 1),然后 5(count 为 2),然后 2(count 为 3),然后 1(count 为 4)。此时 x > 1 为假,所以循环结束,输出是 4。有两个习惯能保住这些分:在每次循环之前而不是之后检验条件;以及每一次循环都新写一行 - 想把这些值记在脑子里,正是追踪出错的原因。

探索

跟踪表

逐步执行循环并填写跟踪表,每轮通过一行。

词汇 训练
English 中文 拼音
trace table/treɪs ˈteɪbl/ 追踪表 zhuī zōng biǎo
7.6

测试数据

测试数据(test data)是你用来测试一个程序的数据。有四种你必须知道的类型。

类型 意义 例子(年龄 0–120 允许)
正常数据(normal) 应当被接受的合理数据 25
异常数据(abnormal) 应当被拒绝的错误数据 -4 或 "cat"
极端数据(extreme) 仍被允许的最大和最小值 0 和 120
边界数据(boundary) 一个限制每一侧的值(一个允许,一个不) 120 和 121
词汇 训练
English 中文 拼音
normal/ˈnɔːml/ 正常数据 zhèng cháng shù jù
abnormal/əbˈnɔːml/ 异常数据 yì cháng shù jù
extreme/ekˈstriːm/ 极端数据 jí duān shù jù
boundary/ˈbaʊndəri/ 边界数据 biān jiè shù jù
7.7

标准解题方法

你必须知道这些常见的算法。

线性查找

线性查找 从列表开头开始,将每个项目与目标值逐一比较。当找到目标值或列表结束时无需继续查找。列表不需要预先排序。以下示例使用位置 1 到 4。

DECLARE List : ARRAY[1:4] OF INTEGER
DECLARE I, SearchValue : INTEGER
DECLARE Found : BOOLEAN
List[1] ← 8
List[2] ← 3
List[3] ← 5
List[4] ← 1
INPUT SearchValue
Found ← FALSE
I ← 1
WHILE I <= 4 AND NOT Found
    IF List[I] = SearchValue
      THEN
        Found ← TRUE
    ENDIF
    I ← I + 1
ENDWHILE
OUTPUT Found

范例对比。 查找 5 时依次比较了 8、3 和 5:共三次比较,此时 Found 变为 TRUE。第四个元素未被检查。查找 9 时需比较所有四个值;Found 保持为 FALSE。在尝试读取位置 5(超出此数组范围)之前停止。

一个八个数的列表从左到右被扫描,搜索 5;前四个不匹配,而第五个被找到
另一个示例:线性查找从起始处开始逐个检查每个项目,直到找到目标值

冒泡排序

冒泡排序 将列表按序排列。比较相邻的值,如果左侧值大于右侧值则交换它们。通常情况下单次遍历不足以完成排序。这种完整版本会重复遍历,直到某次遍历中没有发生任何交换为止。

DECLARE List : ARRAY[1:4] OF INTEGER
DECLARE I, Temp : INTEGER
DECLARE Swapped : BOOLEAN
List[1] ← 8
List[2] ← 3
List[3] ← 5
List[4] ← 1
REPEAT
    Swapped ← FALSE
    FOR I ← 1 TO 3
        IF List[I] > List[I + 1]
          THEN
            Temp ← List[I]
            List[I] ← List[I + 1]
            List[I + 1] ← Temp
            Swapped ← TRUE
        ENDIF
    NEXT I
UNTIL NOT Swapped
OUTPUT List[1], ", ", List[2], ", ", List[3], ", ", List[4]

例题演示。 初始状态为8, 3, 5, 1。在第一轮遍历中,列表依次变为3, 8, 5, 1、3, 5, 8, 1、3, 5, 1, 8。这将最大值移至末尾,但其余元素仍无序。第二轮遍历结束于3, 1, 5, 8;第三轮结束于1, 3, 5, 8。第四轮未发生交换,确认该版本可以停止。每轮开始时将Swapped重置为FALSE;每次发生交换时将TRUE设为相应值。

一个列表,第一对 5 和 2 顺序错误,显示交换成 2 和 5,带一个对每对重复的注释
另一示例中的一轮比较:冒泡排序交换顺序错误的相邻项,然后继续完成本轮遍历

累加与计数

求和 将每个所需值累加到运行总和中:Total ← Total + Value。计数 对每个所需项目加 1:Count ← Count + 1。在处理数值前将两者均初始化为零。

范例示例。 四次尝试输入的值为 −20、4、50 和 6。仅当值大于 −20 且小于 50 时才接受。本例处理的是四次尝试,而非四个被接受的值。

DECLARE I, Count : INTEGER
DECLARE Value, Total : REAL
Total ← 0
Count ← 0
FOR I ← 1 TO 4
    INPUT Value
    IF Value > -20 AND Value < 50
      THEN
        Total ← Total + Value
        Count ← Count + 1
    ENDIF
NEXT I
IF Count > 0
  THEN
    OUTPUT Total, ", ", Count, ", ", Total / Count
  ELSE
    OUTPUT "No accepted values"
ENDIF
尝试输入值 尝试后的总和 尝试后的计数
−20 0 0
4 4 1
50 4 1
6 10 2

严格限制排除了−20和50。两个更新都属于接受测试内部,因此被拒绝的尝试不会改变总数或计数。已接受值的平均值为:

$$\text{Average}=\frac{\text{Total}}{\text{Count}}=\frac{10}{2}=5$$

不要除以四:只有两个值被添加。如果没有值被接受,计数为零,无法计算平均值;应输出提示信息代替除以零的操作。

转移至固定数量的已接受值。 如果任务要求50个已接受值而非四次尝试,请将固定的FOR循环替换为WHILE Count < 50并用ENDWHILE关闭。在其内部保留相同的输入和接受测试。被拒绝的输入不会更改Count,因此会请求另一个输入。完成时Count等于50,尽管尝试次数可能更多。输出总数并按Total / Count计算平均值。

最大、最小与平均

最大值 是最大的值,最小值 是最小的值。平均值 是总数除以值的数量。对于非空列表,从其第一个元素初始化两者。对于每个剩余元素,如果新值更大则替换最大值,如果更小则替换最小值。

示例。 列表为−8, −3, −12, −5。从零开始初始化最大值会失败:没有列表项大于零,算法将输出一个不在列表中的数字。从−8开始有效,无需假设数据为正数。

刚考虑的值 当前最大值 当前最小值
−8 (初始化) −8 −8
−3 −3 −8
−12 −3 −12
−5 −3 −12
DECLARE List : ARRAY[1:4] OF INTEGER
DECLARE I, Maximum, Minimum, Total : INTEGER
List[1] ← -8
List[2] ← -3
List[3] ← -12
List[4] ← -5
Maximum ← List[1]
Minimum ← List[1]
Total ← List[1]
FOR I ← 2 TO 4
    IF List[I] > Maximum
      THEN
        Maximum ← List[I]
    ENDIF
    IF List[I] < Minimum
      THEN
        Minimum ← List[I]
    ENDIF
    Total ← Total + List[I]
NEXT I
OUTPUT Maximum, ", ", Minimum, ", ", Total / 4

最大值为−3,最小值为−12。平均值使用全部四个值计算:

$$\text{Total}=\sum \text{Value}=(-8)+(-3)+(-12)+(-5)=-28$$
$$\text{Average}=\frac{\text{Total}}{\text{Count}}=\frac{-28}{4}=-7$$

平均值位于最小值和最大值之间;这是一个有用的检查,并非证明计算正确的依据。从第一个元素初始化需要非空列表。在读取该元素之前,需单独处理空列表的情况。

词汇 训练
English 中文 拼音
linear search/ˈlɪnɪə sɜːtʃ/ 线性查找 xiàn xìng chá zhǎo
maximum/ˈmæksɪməm/ 最大值 zuì dà zhí
minimum/ˈmɪnɪməm/ 最小值 zuì xiǎo zhí
average/ˈævrɪdʒ/ 平均值 píng jūn zhí
7.8

考试技巧

  • 四个生命周期阶段:分析 → 设计 → 编码 → 测试。抽象保留关键要素;分解将问题拆分为若干部分。
  • 验证检查数据是合理的(范围、长度、类型、存在性、格式检查);核实检查它被正确地复制(一个目视检查或双重输入)。
  • 掌握四种测试数据类型:正常数据(被接受)、异常数据(被拒绝)、极端数据(允许范围内的最大/最小值)、边界数据(限值两侧的数据)。
  • 跟踪表(记录每一步每个变量的值)展示了算法的执行过程。
  • 知道标准算法:线性查找(依次检查每个项)和冒泡排序(交换并排的对直到不需要交换)。

该知识点的互动课程

逐步完成,配合即时检查练习。

历年真题

更多 IGCSE 计算机科学 知识点

登录或创建账户

IGCSE, A-Level & AP