跳到主要内容

数据集合

AP 计算机科学 A · 知识点 4

本主题的视频课程 打开视频页面
13:32

数据集合

用手机拍一张照片。对计算机来说,这根本不像图片——它是一个数字网格,每个像素对应一个数字,大约有一千二百万个。现在尝试…

英语旁白 · 英中内嵌字幕

4.1

数据采集的伦理与社会问题

教学大纲

学习目标 4.1.A: 解释在计算机系统中收集和存储个人数据对隐私构成的风险。

  • 4.1.A.1 使用计算机时,个人隐私面临风险。在开发新程序时,程序员应努力保障用户的个人隐私安全。

学习目标 4.1.B: 解释在使用数据集时识别数据质量及潜在问题的重要性。

  • 4.1.B.1 算法偏见(Algorithmic bias) 指程序中系统性且反复出现的错误,导致特定用户群体遭受不公平的结果。
  • 4.1.B.2 程序员在使用数据推断新信息或得出结论之前,应了解数据集的收集方法以及该方法可能带来的偏见风险。
  • 4.1.B.3 某些数据集不完整或包含不准确的数据。在程序的开发或使用中使用此类数据,可能导致程序运行异常或效率低下。

学习目标 4.1.C: 识别可用于解决问题或回答特定问题的合适数据集。

  • 4.1.C.1 数据集的内容可能与某个特定问题或主题相关,但不一定适用于为其他问题或主题提供正确答案或推断相关信息。

来源:College Board AP 课程与考试说明

English
Server racks in a data centre — large collections of data raise ethical questions about collection and use
Server racks in a data centre — large collections of data raise ethical questions about collection and use

Programs that gather data raise questions of privacy 隐私 and consent 同意. Collect only what is needed, protect it, and be honest about its use. Data can carry bias 偏见 if it does not represent everyone fairly, leading to unfair results – a responsibility that comes with storing information.

词汇 训练
English 中文 拼音
privacy/ˈprɪvəsi/ 隐私 yǐn sī
consent/kənˈsent/ 同意 tóng yì
bias/ˈbaɪəs/ 偏见 piān jiàn
4.2

使用数据集导论

教学大纲

学习目标 4.2.A: 用书面语言或图表表示日常生活中涉及的数据集的模式和算法。

  • 4.2.A.1 数据集 是特定信息或数据条目的集合。
  • 4.2.A.2 数据集可以被操作和分析以解决问题或回答问题。在分析数据集时,集合中的值会被逐个访问和使用,然后根据预期的结果进行处理。
  • 4.2.A.3 数据可以通过图表或表格的形式在图中表示。这种可视化形式可用于规划将要用于操作数据的算法。

来源:College Board AP 课程与考试说明

English
A filing cabinet: collections store many values under one name so algorithms can process them
A filing cabinet: collections store many values under one name so algorithms can process them

A single variable 变量 holds one value; real problems need to store many related values – a class roster, pixels, sensor readings. A data structure 数据结构 organizes a collection so we can store, find, and process items efficiently. The AP course uses three: the array, the ArrayList, and the 2D array.

词汇 训练
English 中文 拼音
variable/ˈveərɪəbl/ 变量 biàn liàng
data structure/ˈdeɪtə ˈstrʌktʃə/ 数据结构 shù jù jié gòu
4.3

数组的创建与访问

教学大纲

学习目标 4.3.A: 编写代码,使用一维(1D)数组对象来表示相关数据的集合。

  • 4.3.A.1 数组用于存储多个相同类型的值。这些值可以是基本类型值,也可以是对象引用。
  • 4.3.A.2 数组的长度在创建时确定,且不可更改。可以通过 length 属性访问数组的长度。
  • 4.3.A.3 当使用关键字 new 创建数组时,其所有元素都会被初始化为该元素数据类型的默认值。int 的默认值为 0,double 的默认值为 0.0,boolean 的默认值为 false,引用类型的默认值为 null。
  • 4.3.A.4 可以使用初始化列表来创建和初始化数组。
  • 4.3.A.5 方括号 [ ] 用于通过索引访问和修改一维数组中的元素。
  • 4.3.A.6 数组的有效索引值范围是从 0 到比数组长度小 1 的数(包含边界)。使用超出此范围的索引值将导致 ArrayIndexOutOfBoundsException(数组下标越界异常)。

来源:College Board AP 课程与考试说明

English

An array 数组 is a fixed-size, ordered collection of same-type values. Indices 索引 run from 0 to length - 1:

A one-dimensional array (a list) with its indices and bounds
A one-dimensional array (a list) with its indices and bounds
int[] nums = new int[5];        // five zeros
int[] vals = {3, 1, 4, 1, 5};   // initialized
int first = vals[0];            // 3
int n = vals.length;            // 5 (a field, not a method)

Accessing an index outside 0..length-1 throws an ArrayIndexOutOfBoundsException.

Worked example. For int[] vals = {3, 1, 4, 1, 5};:

Expression Value
vals[2] 4
vals[vals.length - 1] 5, the last element
vals[1] + vals[3] 2
vals[vals.length] vals[5]: throws the exception

new int[5] fills the array with 0; new double[5] with 0.0, new boolean[5] with false and new String[5] with null. An array's size cannot change once it is made.

词汇 训练
English 中文 拼音
array/əˈreɪ/ 数组 shù zǔ
index/ˈɪndeks/ 索引 suǒ yǐn
4.4

数组遍历

教学大纲

学习目标 4.4.A: 开发用于遍历一维数组元素并确定这些遍历结果的代码。

  • 4.4.A.1 遍历数组是指使用重复语句来访问数组中的所有元素或有序的元素序列。
  • 4.4.A.2 使用索引 for 循环或 while 循环遍历数组时,需要通过索引来访问元素。
  • 4.4.A.3 增强型 for 循环头包含一个变量,称为增强型 for 循环变量。在增强型 for 循环的每次迭代中,增强型 for 循环变量被赋值为元素的副本,而无需使用其索引。
  • 4.4.A.4 为增强型 for 循环变量赋予新值不会改变存储在数组中的值。
  • 4.4.A.5 当数组存储对象引用时,可以通过调用增强型 for 循环变量上的方法来修改属性。这不会改变存储在数组中的对象引用。
  • 4.4.A.6 使用增强型 for 循环编写的用于遍历数组元素的代码可以重写为使用索引 for 循环或 while 循环。

来源:College Board AP 课程与考试说明

English

Traverse 遍历 an array with a for loop (gives the index) or an enhanced for / for-each loop (gives each value, read-only):

for (int i = 0; i < a.length; i++) { a[i] *= 2; }   // can modify
for (int v : a) { System.out.println(v); }          // read each value
Traversing an array with an indexed for loop or an enhanced for loop
Traversing an array with an indexed for loop or an enhanced for loop

Common mistake. An enhanced for loop gives a copy of each value, so this changes nothing in the array:

int[] a = {1, 2, 3};
for (int v : a) {
    v *= 2;        // doubles the copy v only
}
// a is still {1, 2, 3}

To change the elements, use the index loop: a[i] *= 2;. Use an index loop also when the position matters, such as comparing a[i] with a[i + 1]; then stop at i < a.length - 1.

词汇 训练
English 中文 拼音
Traverse/trəˈvɜːs/ 遍历 biàn lì
4.5

实现数组算法

教学大纲

学习目标 4.5.A: 针对涉及数组的特定上下文或规范,开发标准及原创算法的代码,并确定这些算法的运行结果。

  • 4.5.A.1 存在利用数组遍历的标准算法,用于:
    • 确定最小值或最大值
    • 计算总和或平均值
    • 确定是否存在至少一个具有特定属性的元素
    • 确定是否所有元素都具有特定属性
    • 确定具有特定属性的元素数量
    • 访问所有连续的元素对
    • 确定是否存在重复元素
    • 向左或向右移动或旋转元素
    • 反转元素的顺序

来源:College Board AP 课程与考试说明

English

Master these patterns: compute a sum or average, find the max/min, count items meeting a condition, check for a duplicate 重复项, and reverse or shift elements 元素. Each is a traversal with a running result:

int sum = 0;
for (int v : a) sum += v;
double avg = (double) sum / a.length;
Finding the maximum of an array, traced pass by pass
Finding the maximum of an array, traced pass by pass

Worked example. Reverse an array in place by swapping from both ends.

for (int i = 0; i < a.length / 2; i++) {
    int temp = a[i];
    a[i] = a[a.length - 1 - i];
    a[a.length - 1 - i] = temp;
}
i swaps a after
start {3, 1, 4, 1, 5}
0 a[0] and a[4] {5, 1, 4, 1, 3}
1 a[1] and a[3] {5, 1, 4, 1, 3}

a.length / 2 is 2, so the middle element stays put. Looping to a.length would swap every pair twice and put the array back as it was. A swap needs temp: a[i] = a[j]; a[j] = a[i]; loses the old a[i].

词汇 训练
English 中文 拼音
duplicate 重复项 chóng fù xiàng
element/ˈelɪmənt/ 元素 yuán sù
4.6

使用文本文件

教学大纲

学习目标 4.6.A: 编写代码从文本文件中读取数据。

  • 4.6.A.1 文件是用于存储数据的载体,当程序未运行时数据依然保留。在程序执行期间可以检索文件中的数据。
  • 4.6.A.2 可以使用 File 类和 Scanner 类将文件与程序连接。
  • 4.6.A.3 可以通过创建 File 对象来打开文件,并将文件名作为构造函数的参数传入。
    • File(String str) 是 File 构造函数,接受一个用于读取的 String 文件名,其中 str 是文件的目录路径。
  • 4.6.A.4 在使用 File 类时,必须指定如果无法打开指定名称的文件时应如何处理。一种实现方式是在使用该文件的方法头部添加 throws IOException。如果文件名无效,程序将会终止。
  • 4.6.A.5 File 类和 IOException 类属于 java.io 包。必须使用 import 语句才能使这些类在程序中使用。
  • 4.6.A.6 以下 Scanner 方法和构造函数(包括其功能和使用场景)属于 Java 快速参考表:
    • Scanner(File f) 是 Scanner 构造函数,接受一个用于读取的 File 对象。
    • int nextInt() 返回从文件或输入源中读取的下一个 int 值(如果可用)。如果不存在下一个 int 值或超出范围,将导致 InputMismatchException。
    • double nextDouble() 返回从文件或输入源中读取的下一个 double 值。如果不存在下一个 double 值,将导致 InputMismatchException。
    • boolean nextBoolean() 返回从文件或输入源中读取的下一个 boolean 值。如果不存在下一个 boolean 值,将导致 InputMismatchException。
    • String nextLine() 将从文件或输入源中读取的下一行文本作为 String 返回;如果在调用另一个从文件或输入源读取数据的 Scanner 方法后立即调用该方法,可能会返回空字符串。
    • String next() 返回从文件或输入源中读取的下一个 String。
    • boolean hasNext() 如果文件或输入源中存在下一个可读取项则返回 true;否则返回 false。
    • void close() 关闭此扫描器。
    • 排除说明: 从键盘接收输入不在 AP 计算机科学 A 课程和考试范围内。
  • 4.6.A.7 在同一输入源上同时使用 nextLine 和其他 Scanner 方法有时需要编写代码来调整不同方法处理空白字符的方式差异。
    • 排除说明: 在同一输入源上编写或分析同时使用 nextLine 和其他 Scanner 方法的代码不在 AP 计算机科学 A 课程和考试范围内。
  • 4.6.A.8 以下额外的 String 方法(包括其功能和使用场景)属于 Java 快速参考表:
    • String[] split(String del) 返回一个 String 数组,其中每个元素都是 this String 的子串,该字符串围绕给定表达式 del 的匹配项进行了分割。
    • 排除说明: 参数 del 使用的格式称为正则表达式。编写或分析使用任何正则表达式特殊属性(例如 \\*、\\.)的代码不在 AP 计算机科学 A 课程和考试范围内。
  • 4.6.A.9 可以使用 while 循环配合 hasNext 方法作为循环条件,以检测文件中是否仍包含可读元素。
  • 4.6.A.10 当程序不再使用文件时,应将其关闭。通过调用 Scanner 中的 close 方法来关闭文件。

来源:College Board AP 课程与考试说明

English

File and IOException live in java.io, so a program that reads a file needs import java.io.*; as well as import java.util.Scanner; for the Scanner. Opening a file can fail (it might not exist), and Java forces you to handle that – the simplest way is to add throws IOException to the method header 方法头. A Scanner then reads the file line by line, using hasNext... to test before reading:

import java.io.*;
import java.util.Scanner;
...
public static void readFile() throws IOException {
    Scanner f = new Scanner(new File("data.txt"));
    while (f.hasNextLine()) {
        String line = f.nextLine();
    }
}

Reading typed tokens 标记 with nextInt(), nextDouble(), or nextBoolean() throws an InputMismatchException if the next token is the wrong type – for example calling nextInt() when the next thing in the file is the word cat.

词汇 训练
English 中文 拼音
method header 方法头 fāng fǎ tóu
token 标记 biāo jì
4.7

包装类

教学大纲

学习目标 4.7.A: 开发代码以使用由其基本类型派生的 Integer 和 Double 对象,并确定使用这些对象的结果。

  • 4.7.A.1 Integer 类和 Double 类属于 java.lang 包。Integer 对象是不可变的,这意味着一旦创建了 Integer 对象,其属性就不能更改。Double 对象是不可变的,这意味着一旦创建了 Double 对象,其属性就不能更改。
  • 4.7.A.2 自动装箱 是 Java 编译器在基本类型及其对应的对象包装类之间进行的自动转换。这包括将 int 转换为 Integer,以及将 double 转换为 Double。当基本值满足以下条件时,Java 编译器会应用自动装箱:
    • 作为参数传递给期望对应包装类对象的该方法
    • 赋值给对应包装类的变量
  • 4.7.A.3 拆箱 是 Java 编译器从包装类到基本类型的自动转换。这包括将 Integer 转换为 int,以及将 Double 转换为 double。当包装类对象满足以下条件时,Java 编译器会应用拆箱:
    • 作为参数传递给期望对应基本类型值的该方法
    • 赋值给对应基本类型的变量
  • 4.7.A.4 以下类 Integer 方法(包括其功能和使用场景)属于 Java 快速参考的一部分:
    • static int parseInt(String s) 将 String 参数返回为 int。
  • 4.7.A.5 以下类 Double 方法(包括其功能和使用场景)属于 Java 快速参考的一部分:
    • static double parseDouble(String s) 将 String 参数返回为 double。

来源:College Board AP 课程与考试说明

English

An ArrayList stores objects 对象, not primitives 基本类型, so a primitive is wrapped in an object: Integer wraps int, Double wraps double. Java does this with autoboxing 自动装箱 (int to Integer) and unboxing 自动拆箱 (back again) automatically, so you can write list.add(5) and int x = list.get(0).

Autoboxing and unboxing between int and Integer
Autoboxing and unboxing between int and Integer
词汇 训练
English 中文 拼音
object/ˈɒbdʒekt/ 对象 duì xiàng
primitive/ˈprɪmɪtɪv/ 基本类型 jī běn lèi xíng
autoboxing/ˌɔːtəʊˈbɒksɪŋ/ 自动装箱 zì dòng zhuāng xiāng
unboxing/ʌnˈbɒksɪŋ/ 自动拆箱 zì dòng chāi xiāng
4.8

ArrayList 方法

教学大纲

**学习目标 4.8.A:**使用 ArrayList 对象开发相关对象的集合代码,并确定调用这些对象方法的结果。

  • 4.8.A.1 ArrayList 对象在大小上是可变的,并包含对象引用。
  • 4.8.A.2 The ArrayList constructor ArrayList() constructs an empty list.
  • 4.8.A.3 Java 允许使用泛型类型 ArrayList<E>,其中类型参数 E 指定元素类型。当指定 ArrayList<E> 时,使用 ArrayList 方法时的引用参数和返回类型均为 E 类型。推荐使用 ArrayList<E> 而不是 ArrayList。例如,ArrayList<String> names = new ArrayList<String>(); 允许编译器发现原本会在运行时发现的错误。
  • 4.8.A.4 ArrayList 类属于 java.util 包。必须使用 import 语句才能使该类在程序中可用。
  • 4.8.A.5 以下 ArrayList 方法——包括它们的功能和使用时机——是 Java 快速参考的一部分:
    • int size() 返回列表中的元素数量。
    • boolean add(E obj) appends obj to end of list; returns true.
    • void add(int index, E obj) 插入 obj 在位置 index (0 <= index <= size),将位置 index 及更高位置的元素向右移动(其索引增加 1 ),并将大小增加 1 。
    • E get(int index) 返回列表中位置 index 处的元素。
    • E set(int index, E obj) 将位置 index 处的元素替换为 obj;返回原来位于位置 index 的元素。
    • E remove(int index) 移除位置 index 处的元素,将位置 index + 1 及更高位置的元素向左移动(其索引减 1),并将大小减 1;返回原来位于位置 index 的元素。
  • 4.8.A.6 ArrayList 的索引从 0 开始,到元素总数 - 1 结束。

来源:College Board AP 课程与考试说明

English
What an ArrayList really is

An ArrayList 动态数组 grows and shrinks as you add or remove items. Declare it with the element type in <>:

ArrayList<String> names = new ArrayList<String>();
names.add("Amy");           // append
names.add(0, "Bob");        // insert at index
names.get(0);               // read
names.set(1, "Cara");       // replace
names.remove(0);            // delete, shifts the rest left
names.size();               // count (a method, unlike array.length)

Worked example. The list after each call above:

Call names Returns
add("Amy") [Amy] true
add(0, "Bob") [Bob, Amy] nothing
get(0) [Bob, Amy] "Bob"
set(1, "Cara") [Bob, Cara] "Amy", the old value
remove(0) [Cara] "Bob", the removed value
size() [Cara] 1

Indexes must be from 0 to size() - 1, except that add(index, x) also accepts size(), adding at the end; any other index throws an IndexOutOfBoundsException.

词汇 训练
English 中文 拼音
ArrayList/əˈreɪ lɪst/ 动态数组 dòng tài shù zǔ
4.9

ArrayList 遍历

教学大纲

学习目标 4.9.A: 编写用于遍历 ArrayList 元素并确定这些遍历结果的代码。

  • 4.9.A.1 遍历 ArrayList 是指使用迭代或递归语句来访问 ArrayList 中的所有元素或有序序列。
  • 4.9.A.2 在遍历 ArrayList 时删除元素需要使用特殊技术,以避免跳过元素。
  • 4.9.A.3 尝试访问超出其范围的下标值将导致 IndexOutOfBoundsException(下标越界异常)。
  • 4.9.A.4 在使用增强 for 循环遍历 ArrayList 的同时改变其大小可能会导致 ConcurrentModificationException(并发修改异常)。因此,当使用增强 for 循环遍历 ArrayList 时,不应添加或删除元素。

来源:College Board AP 课程与考试说明

English

Traverse with an index loop or a for-each loop, just like arrays (use size() and get(i)):

for (int i = 0; i < list.size(); i++) { ... list.get(i) ... }
for (String s : list) { ... }

Exam skill: when removing items in an index loop, either loop backwards or do not increment i after a removal – otherwise removing shifts elements left and you skip one. And never add or remove elements while traversing an ArrayList with a for-each loop: changing its size mid-loop throws a ConcurrentModificationException, so use an index loop (backwards, as above) whenever you must remove.

4.10

实现 ArrayList 算法

教学大纲

学习目标 4.10.A: 针对特定上下文或规范,为 ArrayList 对象开发标准及原创算法代码,并确定这些算法的运行结果。

  • 4.10.A.1 存在利用遍历操作的标准 ArrayList 算法,用于:
    • 确定最小值或最大值
    • 计算总和或平均值
    • 判断是否至少有一个元素具有特定属性
    • 判断所有元素是否具有特定属性
    • 统计具有特定属性的元素数量
    • 访问所有连续的元素对
    • 判断是否存在重复元素
    • 向左或向右移动或旋转元素
    • 反转元素的顺序
    • 插入元素
    • 删除元素
  • 4.10.A.2 某些算法需要同时遍历多个 String、数组或 ArrayList 对象。

来源:College Board AP 课程与考试说明

English

The same algorithms 算法 as arrays – max/min, count, sum – plus insertion and deletion that arrays cannot do easily. A common task is to remove all elements matching a condition, handling the index-shift carefully.

Worked example. Remove every even number from nums, which holds [2, 4, 5, 6].

A forward loop with i++ after every pass goes wrong:

i nums.get(i) action nums after
0 2 remove [4, 5, 6]
1 5 keep [4, 5, 6]
2 6 remove [4, 5]

The 4 slid into index 0 after the first removal and was never checked. Looping backwards avoids this, because removing shifts only elements already checked:

for (int i = nums.size() - 1; i >= 0; i--) {
    if (nums.get(i) % 2 == 0) {
        nums.remove(i);
    }
}

This leaves [5].

词汇 训练
English 中文 拼音
algorithm/ˈælɡərɪθəm/ 算法 suàn fǎ
4.11

二维数组的创建与访问

教学大纲

学习目标 4.11.A: 开发用于使用二维(2D)数组对象表示相关数据集合的代码。

  • 4.11.A.1 二维数组存储为数组的数组。因此,二维数组的创建和索引方式与一维数组对象类似。二维数组的大小在创建时确定,且不可更改。二维数组可以存储基本数据类型或对象引用数据。
    • 排除说明: 非矩形二维数组对象不在 AP 计算机科学 A 课程和考试的范围内。
  • 4.11.A.2 当使用关键字 new 创建二维数组时,其所有元素均初始化为元素数据类型的默认值。int 的默认值为 0,double 的默认值为 0.0,boolean 的默认值为 false,引用类型的默认值为 null。
  • 4.11.A.3 用于创建和初始化二维数组的初始化列表由表示一维数组的初始化列表组成;例如,int[][] arr2D = { {1, 2, 3}, {4, 5, 6} };。
  • 4.11.A.4 方括号 [row][col] 用于访问和修改二维数组中的元素。为了考试的目的,当访问位于 arr[first][second] 的元素时,第一个索引用于行,第二个索引用于列。
  • 4.11.A.5 可以使用二维数组名称和包含行索引的单组方括号来访问作为二维数组一行的单个数组。
  • 4.11.A.6 可以通过 length 属性访问二维数组中包含的行数。二维数组的有效行索引值是从 0 到行数减一(即数组长度减一),包含两端。可以通过二维数组中某一行的一维数组的 length 属性访问二维数组中包含的列数。二维数组的有效列索引值是从 0 到该任意给定行的列数减一(即该行长度减一),包含两端。例如,给定名为 values 的二维数组,行数为 values.length,列数为 values[0].length。使用超出这些范围的索引值将导致出现 ArrayIndexOutOfBoundsException。

来源:College Board AP 课程与考试说明

English

A 2D array 二维数组 is a grid (rows and columns) – an array of arrays:

A two-dimensional array (a table) with row and column indices
A two-dimensional array (a table) with row and column indices
int[][] grid = new int[3][4];   // 3 rows, 4 columns
grid[r][c] = 7;                 // row r, column c
int rows = grid.length;         // 3
int cols = grid[0].length;      // 4
A Java 2D array: grid[row][col], with both indexes starting at 0
A Java 2D array: grid[row][col], with both indexes starting at 0
探索

按行和列索引2维数组

2维数组是一个由 [row][col] 寻址的网格。移动索引,观察它们选择哪个单元格——先行后列,均从 0 开始计数。

词汇 训练
English 中文 拼音
2D array/ˌtuː ˈdiː əˈreɪ/ 二维数组 èr wéi shù zǔ
4.12

二维数组遍历

教学大纲

学习目标 4.12.A: 编写用于遍历二维数组元素并确定这些遍历结果的代码。

  • 4.12.A.1 嵌套迭代语句用于遍历和访问二维数组中的所有或有序序列的元素。由于二维数组被存储为数组的数组,因此使用 for 循环和增强型 for 循环遍历二维数组的方式与一维数组对象类似。可以编写嵌套迭代语句以按行优先顺序、列优先顺序或唯一定义的顺序遍历二维数组。行优先顺序指的是遍历沿每一行进行的二维数组元素排序方式,而列优先顺序遍历则是沿每一列向下进行。
  • 4.12.A.2 用于遍历二维数组的嵌套增强型 for 循环的外层循环遍历的是行。因此,外层增强型 for 循环变量必须是每一行的类型,即一维数组。内层循环遍历单行。因此,内层增强型 for 循环变量必须与存储在一维数组中的元素类型相同。将新值赋给增强型 for 循环变量不会改变数组中存储的值。

来源:College Board AP 课程与考试说明

English
Traversing a 2-D array

Visit every cell with nested loops 嵌套循环 – the outer over rows, the inner over columns (row-major order 行主序):

for (int r = 0; r < grid.length; r++)
    for (int c = 0; c < grid[0].length; c++)
        System.out.print(grid[r][c]);

To go column by column (column-major order), swap the loops: the outer over c < grid[0].length, the inner over r < grid.length, still writing grid[r][c]. A common mistake is to use grid.length as the column limit: in a 3 × 4 grid that skips column 3, and in a 4 × 3 grid it throws an ArrayIndexOutOfBoundsException.

词汇 训练
English 中文 拼音
nested loop/ˈnestɪd luːp/ 嵌套循环 qiàn tào xún huán
row-major order/rəʊ ˈmeɪdʒə ˈɔːdə/ 行主序 xíng zhǔ xù
4.13

实现二维数组算法

教学大纲

学习目标 4.13.A: 针对特定情境或规范中涉及二维数组的标准及原创算法编写代码,并确定这些算法的执行结果。

  • 4.13.A.1 存在利用二维数组遍历的标准算法,用于:
    • 确定所有元素的最小值或最大值,或指定行、列或其他子区域的最小值或最大值;
    • 计算所有元素的总和或平均值,或指定行、列或其他子区域的总和或平均值;
    • 确定整个二维数组或指定行、列或其他子区域中是否存在至少一个具有特定属性的元素;
    • 确定整个二维数组或指定行、列或其他子区域中的所有元素是否具有特定属性;
    • 确定整个二维数组或指定行、列或其他子区域中具有特定属性的元素数量;
    • 访问所有连续的元素对;
    • 确定整个二维数组或指定行、列或其他子区域中是否存在重复元素;
    • 将行中的元素向左或向右移动,或将列中的元素向上或向下移动;
    • 反转行或列中元素的顺序。

来源:College Board AP 课程与考试说明

English

Typical grid tasks: sum a row or column, find the max in the grid, count matching cells, or sum a diagonal (where r == c). Each is a nested traversal with a running result.

Row-major and column-major traversal of a 2D array
Row-major and column-major traversal of a 2D array

Worked example. Find the sum of each column of

int[][] m = { {1, 2, 3},
              {4, 5, 6} };
for (int c = 0; c < m[0].length; c++) {
    int colSum = 0;                  // reset for each column
    for (int r = 0; r < m.length; r++) {
        colSum += m[r][c];
    }
    System.out.print(colSum + " ");
}

The outer loop picks a column, the inner loop goes down it: $1 + 4 = 5$, $2 + 5 = 7$, $3 + 6 = 9$, so the output is 5 7 9. colSum is set to 0 inside the outer loop; declared before both loops, it would print the running totals 5 12 21. The main diagonal of a square grid needs only one loop: sum += g[i][i];.

4.14

查找算法

教学大纲

学习目标 4.14.A: 开发用于线性搜索算法的代码,以在集合中搜索特定信息并确定执行搜索的结果。

  • 4.14.A.1 线性搜索算法 是标准算法,按顺序逐个检查元素,直到找到目标值或已检查完数组或 ArrayList 中的所有元素为止。线性搜索可以从数组或 ArrayList 的任一端开始。
  • 4.14.A.2 当将线性搜索算法应用于二维数组时,必须逐行访问,然后对二维数组的每一行应用线性搜索。

来源:College Board AP 课程与考试说明

English
Binary search: halve and conquer
  • Linear search 线性搜索 checks each element in turn – works on any list, taking up to $n$ steps.
  • Binary search 二分搜索 works only on a sorted 已排序 list: check the middle, then discard the half that cannot contain the target, repeating. It takes about $\log_2 n$ steps – far faster on large data.
Binary search halves the range at each step
Binary search halves the range at each step
Linear search checks every element in turn until the target is found
Linear search checks every element in turn until the target is found
int lo = 0, hi = a.length - 1;
while (lo <= hi) {
    int mid = (lo + hi) / 2;
    if (a[mid] == target) return mid;
    else if (a[mid] < target) lo = mid + 1;
    else hi = mid - 1;
}

Exam skill: binary search requires sorted data; know how many comparisons it makes and how lo, hi, mid update.

Worked example. Search for target = 40 in the sorted array {3, 9, 14, 23, 31, 42, 55} (indices 0–6). Start lo=0, hi=6:

  • mid = (0+6)/2 = 3, a[3]=23 < 40, so lo = 4;
  • mid = (4+6)/2 = 5, a[5]=42 > 40, so hi = 4;
  • mid = (4+4)/2 = 4, a[4]=31 < 40, so lo = 5;
  • now lo (5) > hi (4), so the loop ends – 40 is not present.

Each step halved the range, so even this miss took only three comparisons.

探索

比较线性搜索和二分搜索

线性搜索依次检查每个元素;二分搜索每一步将有序列表减半。观察二分搜索以远较少的比较次数找到目标值。

词汇 训练
English 中文 拼音
Linear search/ˈlɪnɪə sɜːtʃ/ 线性搜索 xiàn xìng sōu suǒ
Binary search/ˈbaɪnəri sɜːtʃ/ 二分搜索 èr fēn sōu suǒ
sorted/ˈsɔːtɪd/ 已排序 yǐ pái xù
4.15

排序算法

教学大纲

学习目标 4.15.A: 确定执行排序算法的每一步骤,以对一个集合中的元素进行排序。

  • 4.15.A.1 选择排序(Selection sort)和插入排序(Insertion sort)是迭代式排序算法,可用于对数组或 ArrayList 中的元素进行排序。
  • 4.15.A.2 选择排序 反复从列表的未排序部分中选择最小(或最大)的元素,并将其交换到已排序部分的正确(且最终)位置。
  • 4.15.A.3 插入排序 通过将已排序部分的元素移动以腾出空间,将列表未排序部分的一个元素插入到已排序部分的正确位置(但不一定是最终位置)。

来源:College Board AP 课程与考试说明

English
Insertion sort
Bubble sort, pass by pass
  • Selection sort 选择排序 repeatedly finds the smallest remaining element and swaps it into place.
  • Insertion sort 插入排序 grows a sorted front, inserting each new element where it belongs.
An insertion sort, shifting each key into place pass by pass
An insertion sort, shifting each key into place pass by pass

Both are simple and take about $n^2$ steps on average – fine for small arrays. Be able to trace the array after each pass.

探索

观看排序算法对列表进行排序

排序将元素重新排列成有序状态。逐步执行选择排序/插入排序,观察已排序区域每次增加一个元素的过程。

词汇 训练
English 中文 拼音
Selection sort/sɪˈlekʃn sɔːt/ 选择排序 xuǎn zé pái xù
Insertion sort/ɪnˈsɜːʃn sɔːt/ 插入排序 chā rù pái xù
4.16

递归

教学大纲

学习目标 4.16.A: 确定调用递归方法后的结果。

  • 4.16.A.1 递归方法是指调用自身的方法。递归方法至少包含一个基准情况(base case),用于终止递归,以及至少一个递归调用。递归是另一种形式的重复。
  • 4.16.A.2 每次递归调用都有自己独立的一组局部变量,包括参数。参数的值记录了递归过程的进展,这类似于循环控制变量的值记录循环的进展。
  • 4.16.A.3 任何递归解决方案都可以通过使用迭代方法来重现,反之亦然。
    • 排除声明: 编写递归代码不在 AP 计算机科学 A 课程和考试范围内。

来源:College Board AP 课程与考试说明

English
Recursion & the call stack

Recursion 递归 is a method that calls itself on a smaller input. It needs a base case 基本情况 that stops the calls, and a recursive case 递归情形 that moves toward the base:

public static int factorial(int n) {
    if (n <= 1) return 1;          // base case
    return n * factorial(n - 1);   // recursive case
}

Deep recursion without a reachable base case can cause a stack overflow 栈溢出.

Recursion and iteration are interchangeable. Any recursive solution can be rewritten with a loop (an iterative 迭代的 approach), and any loop can be rewritten with recursion - they solve the same problems. The factorial above is identical in effect to an iterative version:

public static int factorial(int n) {
    int result = 1;
    for (int i = 2; i <= n; i++) result *= i;   // same answer, no self-call
    return result;
}

So the choice is about clarity, not capability: recursion reads naturally for problems with a self-similar structure (trees, merge sort), while iteration avoids the memory cost of stacking a call frame per step. The exam may ask you to convert one into the other.

探索

展开递归调用

一个递归方法在输入规模缩小到基本情况之前会调用自身,随后结果逐层返回。逐步执行以观察调用栈的构建与展开过程。

词汇 训练
English 中文 拼音
Recursion/rɪˈkɜːʃn/ 递归 dì guī
base case/beɪs keɪs/ 基本情况 jī běn qíng kuàng
recursive case/rɪˈkɜːsɪv keɪs/ 递归情形 dì guī qíng xíng
stack overflow/stæk ˌəʊvəˈfləʊ/ 栈溢出 zhàn yì chū
iterative/ˈɪtərətɪv/ 迭代的 dié dài de
4.17

递归查找与排序

教学大纲

学习目标 4.17.A: 确定执行使用字符串或集合的递归算法的结果。

  • 4.17.A.1 递归可用于遍历 String 对象、数组和 ArrayList 对象。

学习目标 4.17.B: 确定用于在集合中搜索信息的二分查找算法每次迭代的结果。

  • 4.17.B.1 数据必须处于已排序状态才能使用二分查找算法。二分查找(Binary search) 从已排序的数组或 ArrayList 的中间开始,在每次递归调用中排除该数组或 ArrayList 的一半元素,直到找到目标值或所有元素均被排除为止。
  • 4.17.B.2 二分查找通常比线性查找更高效。
    • 排除声明: 除线性查找和二分查找之外的其他搜索算法不在 AP 计算机科学 A 课程和考试范围内。
  • 4.17.B.3 二分查找算法既可以以迭代方式编写,也可以以递归方式编写。

学习目标 4.17.C: 确定归并排序算法在用于对集合进行排序时每次迭代的结果。

  • 4.17.C.1 归并排序(Merge sort) 是一种递归排序算法,可用于对数组或 ArrayList 中的元素进行排序。
    • 排除声明: 除选择排序、插入排序和归并排序之外的其他排序算法不在 AP 计算机科学 A 课程和考试范围内。
  • 4.17.C.2 归并排序反复将数组划分为更小的子数组,直到每个子数组仅包含一个元素,然后递归地将已排序的子数组合并在一起,最终形成有序的数组。

来源:College Board AP 课程与考试说明

English
Merge sort: split, then merge

Recursion powers efficient algorithms. Binary search can be written recursively (search the correct half). Merge sort 归并排序 splits the array in half, sorts each half recursively, then merges the two sorted halves – taking about $n\log_2 n$ steps, much faster than selection or insertion sort on large data.

Merge sort splits the array to single elements, then merges sorted halves back up
Merge sort splits the array to single elements, then merges sorted halves back up

Worked example. Trace factorial(4). Each call defers to a smaller one: factorial(4) = 4 * factorial(3) = 4 * 3 * factorial(2) = 4 * 3 * 2 * factorial(1). factorial(1) hits the base case and returns 1, so the calls unwind inward: 2 * 1 = 2, then 3 * 2 = 6, then 4 * 6 = 24. Writing each call above its returned value is the reliable way to trace recursion.

Exam skill: trace a recursive method by writing out each call and its return value, and know that merge sort's efficiency ($n\log n$) beats the $n^2$ simple sorts.

词汇 训练
English 中文 拼音
Merge sort/mɜːdʒ sɔːt/ 归并排序 guī bìng pái xù
4.17

考试技巧

English
  • Weigh both benefits and harms of collecting data — this unit is tested through short written justification, not code.
  • Protect personally identifiable information (PII) 个人身份信息 and explain privacy and security risks in context.
  • Name real harms: data breaches, surveillance, and algorithmic bias from unrepresentative data.
  • Respect intellectual property and licensing when you reuse code or data.
  • Give a specific, reasoned answer — a vague "it could be bad" earns no marks.
词汇 训练
English 中文 拼音
personally identifiable information/ˈpɜːsənəli aɪˈdentɪfaɪəbl ˌɪnfəˈmeɪʃn/ 个人身份信息 gè rén shēn fèn xìn xī

该知识点的互动课程

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

历年真题

更多 AP 计算机科学 A 知识点

登录或创建账户

IGCSE, A-Level & AP