← Course Hub← 课程主页 ← All Units← 返回单元列表
H I G H  S C H O O L  C O M P U T E R  S C I E N C E
Solutions答案与解析

Strings and Text Processing字符串与文本处理

Worked Solutions · AP CSP-Feeder · US / ON / BC / AB Styles详细解析 · AP CSP 衔接 · 美 / 安 / 卑 / 阿省风格

EASY MEDIUM HARD 🇺🇸 US 🇨🇦 ON 🇨🇦 BC 🇨🇦 AB Honors荣誉级


PART I  ·  SHORT RESPONSE第一部分  ·  短答题AP CSP-style MCQ + ON/BC short answer · 25 marksAP CSP 风格选择题 + 安/卑省考短答 · 共 25 分

Section A · Short ResponseA 部分 · 短答题

Q1 EASY 🇺🇸 US AP CSP-style MCQAP CSP 风格选择题 §1 String Basics and Indexing字符串基础与索引 [3 marks][3 分]

Given s = "Python", which expression evaluates to "t"?给定 s = "Python",哪个表达式的值为 "t"

Answer: (B) s[2]答案:(B) s[2] A1 A1 A1

Index map for "Python": P=0, y=1, t=2, h=3, o=4, n=5. So s[2] = "t"."Python" 的索引映射:P=0, y=1, t=2, h=3, o=4, n=5。因此 s[2] = "t"。

(A) s[1] = "y", not "t".s[1] = "y",不是 "t"。
(C) s[-1] = "n" (last character).s[-1] = "n"(最后一个字符)。
(D) s[3] = "h".s[3] = "h"。
Insight:关键点: Python uses zero-based indexing. The character at position 0 is always the first character. A common error is writing s[1] expecting the first character -- that is an off-by-one mistake.Python 使用从零开始的索引。位置 0 处的字符始终是第一个字符。常见错误是写 s[1] 期望得到第一个字符,这是差一错误(off-by-one)。
Q2 EASY 🇺🇸 US AP CSP-style MCQAP CSP 风格选择题 §2 String Slicing字符串切片 [3 marks][3 分]

What does "computer"[3:6] evaluate to?"computer"[3:6] 的值是什么?

Answer: (B) "put"答案:(B) "put" A1 A1 A1

Index map: c=0, o=1, m=2, p=3, u=4, t=5, e=6, r=7. Slice [3:6] includes indices 3, 4, 5 and excludes 6. Characters at 3, 4, 5 are p, u, t = "put".索引映射:c=0, o=1, m=2, p=3, u=4, t=5, e=6, r=7。切片 [3:6] 包含索引 3、4、5,不含 6。这些位置的字符为 p、u、t = "put"。

(D) "mpu" comes from indices 2, 3, 4 which is [2:5], not [3:6]."mpu" 来自索引 2、3、4,即 [2:5],不是 [3:6]
Insight:关键点: The stop index in a slice is always excluded. [3:6] gives 3 characters (indices 3, 4, 5), not 4. To get n characters starting at index k, write [k : k+n].切片的 stop 索引始终不包含。[3:6] 给出 3 个字符(索引 3、4、5),不是 4 个。要从索引 k 开始取 n 个字符,写 [k : k+n]
Q3 EASY 🇨🇦 ON ON Provincial-style安大略省考风格 §3 String Methods and Immutability字符串方法与不可变性 [4 marks][4 分]
word = "hello"
word.upper()
print(word)
Answers: (a) hello   (b) strings are immutable   (c) word = word.upper()答案:(a) hello   (b) 字符串不可变   (c) word = word.upper()

(a) Output [1](a) 输出 [1]

hello A1 -- word is unchanged.hello A1 -- word 未改变。

(b) Why word does not change [2](b) word 为何不变 [2]

Strings are immutable in Python M1: upper() returns a new string object with the uppercased characters, but does not modify the original string that word refers to. A1 Because the return value is not assigned to anything, it is discarded.Python 中字符串是不可变的 M1upper() 返回一个包含大写字符的新字符串对象,但不修改 word 所引用的原始字符串。A1 因为返回值没有赋给任何变量,所以被丢弃了。

(c) Fixed line 2 [1](c) 修改后的第 2 行 [1]

word = word.upper()

A1 Assigning the return value back to word stores the new uppercased string.A1 将返回值重新赋给 word,即可保存新的大写字符串。

Insight:关键点: This is the single most common string method mistake. Every string method returns a new string. If you do not assign it, the result is lost. Always write s = s.method(), not just s.method(), when you want to update a variable.这是字符串方法中最常见的错误。每个字符串方法都返回一个新字符串。如果不赋值,结果就丢失了。当你想更新变量时,始终写 s = s.method(),而不只是 s.method()
Q4 MEDIUM 🇨🇦 AB AB/Universal Applied阿省/通用应用题 §4 Concatenation and Formatting拼接与格式化 [7 marks][7 分]
name  = "Alex"
score = 88
# Program A: result_a = "Student: " + name + ", Score: " + score
# Program B: result_b = "Student: " + name + ", Score: " + str(score)
# Program C: result_c = f"Student: {name}, Score: {score}"
Answers: (a) TypeError   (b) Student: Alex, Score: 88   (c) Student: Alex, Score: 88   (d) C (f-string)答案:(a) TypeError   (b) Student: Alex, Score: 88   (c) Student: Alex, Score: 88   (d) C(f-string)

(a) Program A error [2](a) 程序 A 错误 [2]

TypeError A1: The + operator cannot concatenate a string and an integer directly. score is the integer 88; Python does not auto-convert it to a string when using +. A1TypeError A1+ 运算符不能直接拼接字符串和整数。score 是整数 88;使用 + 时 Python 不会自动将其转换为字符串。A1

(b) Program B output [1](b) 程序 B 输出 [1]

Student: Alex, Score: 88 A1 -- str(88) converts the integer to the string "88" first, enabling concatenation.Student: Alex, Score: 88 A1 -- str(88) 先将整数转换为字符串 "88",从而可以拼接。

(c) Program C output and explanation [3](c) 程序 C 输出及解释 [3]

Student: Alex, Score: 88 A1Student: Alex, Score: 88 A1

The f prefix marks the string as a formatted string literal (f-string). M1 Any expression inside {} is evaluated at runtime and its result is converted to a string and inserted at that position. A1f 前缀将字符串标记为格式化字符串字面量(f-string)。M1 {} 内的任何表达式在运行时被求值,其结果被转换为字符串并插入该位置。A1

(d) Preferred style [1](d) 推荐风格 [1]

C (f-string) is preferred in modern Python A1 because it is more readable and requires no explicit type conversion.现代 Python 中首选 C(f-string)A1,因为可读性更强,无需显式类型转换。

Insight:关键点: AB CSE1110 outcome 2.4.6 names concatenation and interpolation as assessed skills. The TypeError in Program A is one of the most frequent runtime errors beginners encounter: you must convert all non-string values to strings before using +. F-strings handle this automatically.AB CSE1110 结果 2.4.6 将拼接和插值列为评估技能。程序 A 中的 TypeError 是初学者最常遇到的运行时错误之一:使用 + 之前必须将所有非字符串值转换为字符串。F-string 会自动处理这一点。
Q5 MEDIUM 🇨🇦 BC BC Provincial-style卑诗省考风格 §5 Searching Within Strings在字符串中搜索 [8 marks][8 分]
sentence = "the quick brown fox"
Answers: (a) True, bool   (b) 4, -1   (c) 2   (d) use in for boolean check答案:(a) True,布尔型   (b) 4,-1   (c) 2   (d) 只需布尔判断时用 in

(a) "fox" in sentence [2](a) "fox" in sentence [2]

True A1. The in operator returns a bool value (True or False). A1 "fox" is a substring of "the quick brown fox".True A1in 运算符返回布尔值(TrueFalse)。A1 "fox" 是 "the quick brown fox" 的子字符串。

(b) find() results [3](b) find() 结果 [3]

sentence.find("quick") = 4 A1: "quick" starts at index 4 (t=0, h=1, e=2, space=3, q=4). A1sentence.find("quick") = 4 A1:"quick" 从索引 4 开始(t=0, h=1, e=2, 空格=3, q=4)。A1

sentence.find("cat") = -1 A1: find() returns -1 when the substring is not found in the string.sentence.find("cat") = -1 A1find() 在字符串中未找到子字符串时返回 -1。

(c) count("o") [2](c) count("o") [2]

2 A1. The character "o" appears in "brown" (index 10) and "fox" (index 16) -- two non-overlapping occurrences. A12 A1。字符 "o" 出现在 "brown"(索引 10)和 "fox"(索引 16)中,共 2 次不重叠出现。A1

(d) When to use in over find() [1](d) 何时用 in 而非 find() [1]

Use in when you only need to know whether a substring is present (a boolean answer) and do not need its position. A1 It is also cleaner and more readable.当你只需要知道子字符串是否存在(布尔答案)而不需要其位置时,使用 inA1 它也更简洁易读。

Insight:关键点: ON ICS3C A1.2 directly names "count the occurrences of a word or letter" as an assessed skill. The three string search tools cover all the bases: in for existence, find() for position, count() for frequency.ON ICS3C A1.2 直接将"计算单词或字母的出现次数"列为评估技能。三种字符串搜索工具涵盖所有情形:in 用于检查存在性,find() 用于获取位置,count() 用于计算频率。
PART II  ·  EXTENDED RESPONSE第二部分  ·  简答题AP CSP-feeder FRQ + Honors · 31 marksAP CSP 衔接简答题 + 荣誉级 · 共 31 分

Section B · Extended ResponseB 部分 · 简答题

Q6 MEDIUM 🇺🇸 US AP CSP-feeder FRQAP CSP 衔接简答题 §6 Looping Over Characters遍历字符 [8 marks][8 分]
Answers: (a) 5 vowels, output = 5   (b) len=9, i=0..8   (c) for-range when index needed答案:(a) 5 个元音,输出 = 5   (b) len=9,i=0..8   (c) 需要索引时用 for-range

(a) Trace Program A [3](a) 追踪程序 A [3]

chchVowel?元音?countcount
eYes1
dNo1
uYes2
cNo2
aYes3
tNo3
iYes4
oYes5
nNo5

Final output: 5 A1A1A1 (1 mark for correct vowel identification, 1 for correct count trace, 1 for output).最终输出:5 A1A1A1(1 分正确识别元音,1 分正确追踪计数,1 分输出)。

(b) len and i values in Program B [2](b) 程序 B 中 len 和 i 的值 [2]

len("education") = 9 A1. i takes values 0, 1, 2, 3, 4, 5, 6, 7, 8 A1.len("education") = 9 A1i 取值为 0, 1, 2, 3, 4, 5, 6, 7, 8 A1

(c) When to choose for-range [3](c) 何时选择 for-range [3]

Choose for-range when you need the index (position) of the character, not just its value. M1 Example: replacing specific characters -- to change every vowel to "*" you need s[i] and the index to build the new string character by character. A1 Accept: comparing adjacent characters (s[i] vs s[i+1]), checking if a character at a specific position satisfies a condition. A1当你需要字符的索引(位置)而不只是其值时,选择 for-range。M1 例如:替换特定字符,要将每个元音改为 "*",你需要 s[i] 和索引,逐字符构建新字符串。A1 也接受:比较相邻字符(s[i]s[i+1])、检查特定位置的字符是否满足条件等场景。A1

Insight:关键点: The for-each style (for ch in s) is the Pythonic default because it is cleaner. Use for-range only when the index matters. A real-world case: validating an ISBN number requires checking the character at each specific position -- position 0 must be a digit, position 9 can be "X", etc.for-each 风格(for ch in s)是 Python 的默认首选,因为更简洁。只有当索引重要时才使用 for-range。实际案例:验证 ISBN 号需要检查每个特定位置的字符,位置 0 必须是数字,位置 9 可以是 "X" 等。
Q7 MEDIUM 🇨🇦 ON ON Provincial-style安大略省考风格 §3 + §5 Methods + Searching方法 + 搜索 [8 marks][8 分]
Answers: (a) [" Alice ", " Biology ", " 92 "]   (b) ["alice", "biology", "92"]   (c) see below答案:(a) [" Alice ", " Biology ", " 92 "]   (b) ["alice", "biology", "92"]   (c) 见下

(a) fields after line 2 [2](a) 第 2 行后 fields [2]

[" Alice ", " Biology ", " 92 "] A1A1. split(",") splits on each comma and preserves leading/trailing whitespace within each piece.[" Alice ", " Biology ", " 92 "] A1A1split(",") 在每个逗号处分割,并保留每段中的首尾空白。

(b) clean after line 3 [3](b) 第 3 行后 clean [3]

["alice", "biology", "92"] A1["alice", "biology", "92"] A1

For the first element " Alice ": strip() removes the leading and trailing spaces to give "Alice" A1; lower() then converts all letters to lowercase to give "alice" A1.对于第一个元素 " Alice "strip() 去除首尾空格,得到 "Alice" A1lower() 将所有字母转为小写,得到 "alice" A1

(c) Output of lines 4, 5, 6 [3](c) 第 4、5、6 行输出 [3]

Line 4: ["alice", "biology", "92"] A1第 4 行:["alice", "biology", "92"] A1

Line 5: clean[0] is "alice". "alice".count("l") = 1 A1 (only one "l" in "alice").第 5 行:clean[0]"alice""alice".count("l") = 1 A1("alice" 中只有一个 "l")。

Line 6: clean[1] is "biology". "bio" in "biology" = True A1 ("bio" is the first three characters of "biology").第 6 行:clean[1]"biology""bio" in "biology" = True A1("bio" 是 "biology" 的前三个字符)。

Insight:关键点: The pattern strip-then-lower is the standard CSV-cleaning idiom. Real-world data almost always has inconsistent whitespace and capitalisation. Applying strip() before lower() (not after) ensures spaces are removed first, which is slightly more efficient.先 strip 再 lower 是标准的 CSV 清理惯例。真实数据几乎总有不一致的空白和大小写。先 strip()lower()(不是反过来)确保先去除空格,效率略高。
Q8 HARD 🇨🇦 BC 🇺🇸 US AP CSP-feeder FRQAP CSP 衔接简答题 §2 + §6 Slicing + loop reversal切片 + 循环反转 [8 marks][8 分]
Answers: (a) "racecar"   (b) "racecar"   (c) s == s[::-1]答案:(a) "racecar"   (b) "racecar"   (c) s == s[::-1]

(a) Method 1 output and slice explanation [3](a) 方法 1 输出及切片解释 [3]

Output: racecar A1输出:racecar A1

[::-1]: start is omitted (defaults to end of string), stop is omitted (defaults to beginning), step is -1 (traverse backwards). M1 The result is the entire string read from right to left, i.e., reversed. A1 Since "racecar" is a palindrome, the reverse equals the original.[::-1]:start 省略(默认为字符串末尾),stop 省略(默认为开头),step 为 -1(从后往前遍历)。M1 结果是从右到左读取整个字符串,即反转。A1 由于 "racecar" 是回文,反转后等于原字符串。

(b) Trace Method 2 [4](b) 追踪方法 2 [4]

Iteration迭代chrev2
1r"r"
2a"ar"
3c"car"
4e"ecar"
5c"cecar"
6a"acecar"
7r"racecar"

A1A1A1 (1 mark table set-up, 1 mark correct intermediate values, 1 mark final output). Final output: racecar A1. Each iteration prepends ch before rev2, building the reverse character by character.A1A1A1(1 分表格设置,1 分正确中间值,1 分最终输出)。最终输出:racecar A1。每次迭代将 ch 前置于 rev2,逐字符构建反转字符串。

(c) Palindrome expression [1](c) 回文表达式 [1]

s == s[::-1]

A1 This evaluates to True if the string equals its own reverse.A1 当字符串等于其反转时,该表达式值为 True

Insight:关键点: The prepend pattern result = ch + result is the standard loop-based string reversal. It builds the answer backwards because each new character is placed at the front. The slice [::-1] is O(n) and is the preferred one-liner, but knowing the loop version shows you understand what reversal means structurally.前置模式 result = ch + result 是标准的基于循环的字符串反转。它从后往前构建答案,因为每个新字符被放在最前面。切片 [::-1] 是 O(n) 的,是首选的单行写法,但了解循环版本表明你理解反转在结构上的含义。
Q9 HARD Honors荣誉级 🇺🇸 US AP CSP-feeder FRQAP CSP 衔接简答题 §7 Text-Processing Pipeline文本处理流水线 [7 marks][7 分]
Answers: (a) see below   (b) total=9, freq={'the':3,'cat':2,...}   (c) 3 output lines答案:(a) 见下   (b) total=9,freq={'the':3,'cat':2,...}   (c) 3 行输出

(a) text and words [2](a) textwords [2]

text = "the cat sat on the mat and the cat" A1 (lower() lowercases the capital T; strip() removes any leading/trailing whitespace -- none here, so no visible change).text = "the cat sat on the mat and the cat" A1lower() 将大写 T 转为小写;strip() 去除首尾空白,此处无空白,所以无可见变化)。

words = ["the","cat","sat","on","the","mat","and","the","cat"] A1words = ["the","cat","sat","on","the","mat","and","the","cat"] A1

(b) total and freq [3](b) totalfreq [3]

total = 9 A1total = 9 A1

freq = {"the": 3, "cat": 2, "sat": 1, "on": 1, "mat": 1, "and": 1} A1A1 (1 mark for "the":3 and "cat":2; 1 mark for all remaining entries correct).freq = {"the": 3, "cat": 2, "sat": 1, "on": 1, "mat": 1, "and": 1} A1A1(1 分 "the":3 和 "cat":2 正确;1 分其余条目全部正确)。

(c) Three output lines [2](c) 三行输出 [2]

Line 1: Total words: 9 A1第 1 行:Total words: 9 A1

Line 2: Most frequent: 'the' (3 times) A1 (max(freq, key=freq.get) finds the key with the highest value = "the" with count 3).第 2 行:Most frequent: 'the' (3 times) A1max(freq, key=freq.get) 找到值最大的键 = "the",计数为 3)。

Line 3: 'cat' appears: yes第 3 行:'cat' appears: yes

Insight:关键点: This pipeline -- normalise, split, count, report -- is the foundation of text analysis. ON ICS3C A1.2 explicitly requires "count the occurrences of a word or letter." The key insight is that calling lower() before split() ensures "The" and "the" are counted as the same word. Without normalisation, "The" and "the" would be separate dictionary keys.这个流水线(规范化、分割、计数、报告)是文本分析的基础。ON ICS3C A1.2 明确要求"计算单词或字母的出现次数"。关键点是在 split() 之前调用 lower(),确保 "The" 和 "the" 被计为同一个词。如果不规范化,"The" 和 "the" 会是字典中的不同键。
PART III  ·  MODELING / APPLIED第三部分  ·  建模与应用Universal / multi-region applied · 25 marks通用/多地区应用题 · 共 25 分

Section C · Modeling and ApplicationsC 部分 · 建模与应用

Q10 MEDIUM 🇺🇸 US 🇨🇦 ON AP CSP-feeder FRQAP CSP 衔接简答题 §5 + §6 Searching + traversal搜索 + 遍历 [8 marks][8 分]
Answers: (a) upper_count=2   (b) 2, True   (c) upper_count = sum(1 for ch in text if ch.isupper())答案:(a) upper_count=2   (b) 2,True   (c) upper_count = sum(1 for ch in text if ch.isupper())

(a) Trace loop for "Hello5World" [4](a) 追踪 "Hello5World" 的循环 [4]

chisupper()?isupper()?upper_count
HTrue1
eFalse1
lFalse1
lFalse1
oFalse1
5False1
WTrue2
oFalse2
rFalse2
lFalse2
dFalse2

A1A1A1A1 (1 mark correct isupper for H and W; 1 mark digits/lowercase return False; 1 mark correct count progression; 1 mark final count = 2).A1A1A1A1(1 分 H 和 W 的 isupper 正确;1 分数字/小写字母返回 False;1 分正确计数递进;1 分最终计数 = 2)。

(b) Two output values [2](b) 两个输出值 [2]

2 A1 and True A12 A1True A1

(c) One-liner [2](c) 单行写法 [2]

upper_count = sum(1 for ch in text if ch.isupper())

A1A1. sum() over a generator expression that yields 1 for each uppercase character is equivalent to the explicit loop. Accept also: upper_count = sum(ch.isupper() for ch in text) (booleans are integers in Python: True=1, False=0).A1A1。对生成器表达式(每遇一个大写字符产生 1)求 sum(),等价于显式循环。也接受:upper_count = sum(ch.isupper() for ch in text)(Python 中布尔值是整数:True=1,False=0)。

Insight:关键点: Notice that isupper() returns False for the digit "5" -- it only returns True for alphabetic characters that are uppercase. The generator expression one-liner is a pattern worth memorising: sum(condition for item in iterable) counts items satisfying the condition.注意 isupper() 对数字 "5" 返回 False,它只对大写字母字符返回 True。生成器表达式单行写法值得记忆:sum(condition for item in iterable) 计算满足条件的项目数。
Q11 MEDIUM 🇨🇦 ON 🇨🇦 BC ON Provincial-style安大略省考风格 §1 + §2 + §4 Indexing + Slicing + Formatting索引 + 切片 + 格式化 [9 marks][9 分]
Answers: (a) "2024", "06", "15"   (b) "5"   (c) Year: 2024, Month: 06, Day: 15, Last char: 5   (d) immutable; use concatenation答案:(a) "2024","06","15"   (b) "5"   (c) Year: 2024, Month: 06, Day: 15, Last char: 5   (d) 不可变;用拼接

(a) year, month, day [3](a) year、month、day [3]

Index map of "2024-06-15": 2=0, 0=1, 2=2, 4=3, -=4, 0=5, 6=6, -=7, 1=8, 5=9."2024-06-15" 的索引映射:2=0, 0=1, 2=2, 4=3, -=4, 0=5, 6=6, -=7, 1=8, 5=9。

year = date[0:4] = "2024" A1 (indices 0,1,2,3)year = date[0:4] = "2024" A1(索引 0,1,2,3)

month = date[5:7] = "06" A1 (indices 5,6)month = date[5:7] = "06" A1(索引 5,6)

day = date[8:10] = "15" A1 (indices 8,9)day = date[8:10] = "15" A1(索引 8,9)

(b) last_char and negative indexing [2](b) last_char 和负索引 [2]

last_char = "5" A1. Negative index -1 counts from the right: index -1 refers to the last character in the string, which is "5". A1last_char = "5" A1。负索引 -1 从右计数:索引 -1 指字符串的最后一个字符,即 "5"。A1

(c) Output of print(report) [2](c) print(report) 的输出 [2]

Year: 2024, Month: 06, Day: 15, Last char: 5 A1A1Year: 2024, Month: 06, Day: 15, Last char: 5 A1A1

(d) Why date[0]="3" fails and the fix [2](d) date[0]="3" 为何失败及修复 [2]

Strings are immutable A1: individual characters cannot be modified in place. To produce a corrected date string, use string concatenation or slicing: "3" + date[1:] A1. This creates a new string with "3" as the first character followed by the rest of date.字符串是不可变的 A1:不能就地修改单个字符。要生成修改后的日期字符串,使用字符串拼接或切片:"3" + date[1:] A1。这创建了一个以 "3" 为第一个字符、后跟 date 其余部分的新字符串。

Insight:关键点: Date-string parsing with slicing is a classic ON ICS3C A1.2 exercise ("extract a portion"). The slice indices must be exact: [0:4] grabs 4 characters, [5:7] skips the dash at index 4 and grabs 2 characters for the month. Negative indices give clean access to the last few characters without knowing the length.用切片解析日期字符串是经典的 ON ICS3C A1.2 练习("提取一部分")。切片索引必须精确:[0:4] 取 4 个字符,[5:7] 跳过索引 4 处的连字符并取 2 个字符作为月份。负索引可以在不知道长度的情况下干净地访问最后几个字符。
Q12 HARD 🇺🇸 US 🇨🇦 ON 🇨🇦 BC AP CSP-feeder FRQAP CSP 衔接简答题 §3 + §5 + §7 Methods + Search + Pipeline debugging方法 + 搜索 + 流水线调试 [8 marks][8 分]
Answers: (a) "Not found." -- case mismatch   (b) normalise with lower()   (c) "Found!" then "1"答案:(a) "Not found." -- 大小写不匹配   (b) 用 lower() 规范化   (c) "Found!" 然后 "1"

(a) Current output and bug [3](a) 当前输出及错误 [3]

Current output: Not found. A1当前输出:Not found. A1

Bug: the in operator is case-sensitive. M1 sentence = "The Quick Brown Fox" contains "The" with a capital T, but target = "the" is all lowercase. "the" (lowercase) is not a substring of "The Quick Brown Fox" because the capital T at position 0 does not match the lowercase t. A1错误:in 运算符区分大小写。M1 sentence = "The Quick Brown Fox" 包含首字母大写的 "The",但 target = "the" 全是小写。"the"(小写)不是 "The Quick Brown Fox" 的子字符串,因为位置 0 的大写 T 与小写 t 不匹配。A1

(b) Fixed code [3](b) 修复后的代码 [3]

sentence = "The Quick Brown Fox"
target   = "the"
s_lower  = sentence.lower()
if target in s_lower:
    print("Found!")
    print(s_lower.count(target))

M1 Normalise sentence to lowercase before searching. A1 Use the same normalised string for both in and count() to ensure consistent case-insensitive results. A1 Accept also: if target in sentence.lower() and sentence.lower().count(target).M1 搜索前将 sentence 规范化为小写。A1incount() 使用同一个规范化后的字符串,确保不区分大小写的一致结果。A1 也接受:if target in sentence.lower()sentence.lower().count(target)

(c) Correct output [2](c) 正确输出 [2]

Found! A1Found! A1

1 A1 -- "the quick brown fox" (lowercased) contains "the" exactly once, at the start.1 A1 -- "the quick brown fox"(小写后)包含 "the" 恰好一次,在开头。

Insight:关键点: Case-insensitive search is one of the most common bugs in string programs. The fix pattern -- normalise both the haystack and the needle to the same case before comparing -- is a standard technique. Note: the needle (target) is already lowercase here, so only the haystack needs normalising. If both could be mixed case, normalise both: target.lower() in sentence.lower().不区分大小写的搜索是字符串程序中最常见的错误之一。修复模式(在比较之前将被搜索字符串和搜索词都规范化为同一大小写)是标准技术。注意:此处搜索词(target)已经是小写,所以只需规范化被搜索字符串。如果两者都可能是混合大小写,则都规范化:target.lower() in sentence.lower()