跳到正文
IGCSE·Tuition
计算机科学 · 课程

修复差一错误(off-by-one error)

程序给出错误的总和,往往就是刚好差了一轮。

本页内容
  1. 怎样找出出错的那一行?
  2. 例题详解
  3. 要留意的错误
  4. 自我检测
  5. 接下来学什么

**差一错误(off-by-one error)**指循环多运行了一轮或少运行了一轮。它是算法题中最常见的错误之一,考试经常给出一个有问题的循环,要求你修复。

这一课建立在追踪计数控制和条件控制循环的基础上,属于重复与数组模块。一旦出现数组,它就更重要了。

怎样找出出错的那一行?

按以下顺序进行:

  1. 用数字说明循环应该做什么。例如”把前 10 个整数相加,所以 10 轮,答案 55”。
  2. 追踪第一轮和最后一轮。
  3. 数一数代码实际运行了几轮。
  4. 比较。如果代码少了或多了一轮,就检查起始值、结束值和比较符号。

例题详解

一位程序员想求整数 1 到 10 的总和。

Total ← 0
FOR i ← 1 TO 9
   Total ← Total + i
NEXT i
OUTPUT Total

循环取值为 1 到 9,共 9 轮。任务需要 10 轮。

i之后的 Total
11
23
36
410
515
621
728
836
945

输出是 45,但 1 到 10 的总和是 55。缺少的值是 10,而 45 + 10 = 55。修复方法是改结束值:

FOR i ← 1 TO 10

WHILE 循环也可能把同样的错误藏在条件里。下面这个版本本应输出 3 的前四个倍数,即 3、6、9 和 12。

Count ← 0
WHILE Count <= 4 DO
   Count ← Count + 1
   OUTPUT Count * 3
ENDWHILE

Count = 0、1、2、3、4 时测试都为真,所以有 5 轮。它输出 3、6、9、12 和 15。把条件改成 Count < 4,则 Count = 0、1、2、3 时运行,输出 3、6、9 和 12,这才是正确的。

要留意的错误

常见的失误是修改输出,而不是修改循环。

错误的修法: “总和是 45,应该是 55,所以写 OUTPUT Total + 10。”

这只对这一组输入给出 55。循环仍然漏掉最后一个值,换任何其他结束值都会出错。

纠正的方法是修改循环边界,让它运行正确的轮数。然后追踪第二个小例子,例如数字 1 到 3(总和 6)来确认。

自我检测

1. 数组 Score[1:5] 存有五个值,代码是 FOR i ← 0 TO 4。哪里错了?怎样修复?

查看答案

数组的位置从 1 到 5。位置 0 不存在,而位置 5 从未被访问。修复为 FOR i ← 1 TO 5。

2. FOR i ← 5 TO 12 运行几轮?

查看答案

取值为 5、6、7、8、9、10、11、12,共 8 轮。检查:12 - 5 + 1 = 8。

3. 这个循环应该只输出 2、4 和 6,却输出了 2、4、6 和 8。请给出修复方法。

n ← 0
WHILE n < 8 DO
   n ← n + 2
   OUTPUT n
ENDWHILE
查看答案

n = 0、2、4 和 6 时测试为真,所以运行四轮,最后输出 8。把条件改成 WHILE n < 6。这样 n = 0、2 和 4 通过测试,输出为 2、4 和 6。

接下来学什么

接下来用一个正确的循环扫描列表:在给定列表中找最大值。伪代码追踪训练器可以让你逐步运行有问题的循环,观察第一轮和最后一轮。

计算机科学补习的老师可以带来新的出错循环,请你在动笔之前先解释该如何修复。

常见问题

什么是差一错误?

它指循环多运行了一次或少运行了一次,或者下标偏高或偏低了一个位置。常见原因是起始值错、结束值错,或者该用 <= 的地方用了 <。

怎样测试循环有没有差一错误?

在纸上追踪第一轮和最后一轮,并数一数轮数。把你得到的轮数与任务需要的轮数比较。用一个很小的情况,例如三个项目,多出或缺少的一轮就很容易看出来。

把答案加一或减一来修正,可以吗?

不可以。这样只会掩盖错误,换一组输入就会失败。应该修正循环的边界或条件,让循环恰好运行任务需要的轮数,然后用第二个小例子检查结果。

更新于:

下一步

如果你看得出循环不对,但一补就把错误挪到别处,老师可以和你一起追踪修复过程,教你如何同时测试循环的两端。

一小时付费试听课,按所安排老师确认的收费,RM80 起。 其他费用、时间安排及后续课程,在试听课后由家长与老师直接确认。

补习由家长或监护人安排。用 WhatsApp 把这页发给他们,他们就可以替你咨询。

是家长或监护人?在这里咨询

已通过我们的服务帮助 9,000+ 名学生