1.3 · 模式識別
目標: 發現兩個問題共享結構時,讓一個解法服務兩者。
模式識別是什麼
跨問題尋找共同結構,讓一個演算法 —— 也許帶些小變體 —— 解決許多。
例子
模式 1 · 「找最大」
| 問題 | 變的是什麼 |
|---|---|
| 找最高的學生 | 「高」 |
| 找最貴的產品 | 「貴」 |
| 找最長的河流 | 「長」 |
同一演算法 —— max() —— 不同屬性。
模式 2 · 「處理列表每項」
| 問題 | 每項動作 |
|---|---|
| 印每位學生姓名 | |
| 累加全部銷售 | accumulate |
| 給每位家長髮郵件 | send_email |
| 校驗每條條目 | validate |
都是迴圈過一個集合,只變內部動作。
模式 3 · 「排序列表」
| 問題 | 排序鍵 |
|---|---|
| 按分數升序排學生 | score asc |
| 按重量降序 | weight desc |
| 按標題字母排書 | title |
同樣排序演算法;只比較函式變。
為何重要
- 把一種模式實現好後,未來類似任務幾分鐘搞定。
- 代碼變通用 —— 接收列表和函式,對任何東西都能幹。
- 庫就是建立在公認模式上 (
map、filter、reduce)。
實例 · 機器人編程
兩任務:
- 讓機器人畫正方形。
- 讓機器人畫等邊三角形。
模式:「重複(前進、轉角)」N 次。
text
對多邊形每個角:
前進 side_length
轉 exterior_angle1
2
3
2
3
只角度與角數不同。
python
def draw_polygon(sides, length):
for _ in range(sides):
move_forward(length)
turn(360 / sides)1
2
3
4
2
3
4
draw_polygon(4, 100) 畫正方形;draw_polygon(3, 100) 畫三角形;draw_polygon(8, 50) 畫八邊形。
值得知道的模式目錄
| 模式 | 用途 |
|---|---|
| Iterate 迭代 | 走過列表 |
| Accumulate 累加 | 建累計 |
| Filter 篩選 | 保留滿足條件的項 |
| Map 映射 | 變換每一項 |
| Search 搜索 | 找一項 |
| Sort 排序 | 給列表排序 |
| Group 分組 | 把項分類 |
| Aggregate 聚合 | 彙總一組 |
考試式題目
題(4 分): 兩位學生髮現他們寫了類似代碼:一個找最高同學,一個找列表中最貴的書。解釋模式識別如何幫他們寫可複用代碼。
參考答案:
兩題共享**「找最大項」模式:遍歷列表、追蹤迄今最好、最後返回。僅比較屬性(高度 vs 價格)不同。學生可寫通用函式**,接收列表與一個「鍵函式」描述要比較的屬性,例如:
python
def find_max(items, key):
best = items[0]
for item in items[1:]:
if key(item) > key(best):
best = item
return best
find_max(students, key=lambda s: s.height)
find_max(books, key=lambda b: b.price)1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
這單一函式替代兩個專門版、減少 bug、支援未來任何「找最大」任務。
關鍵要點
- 發現共同結構 → 寫通用代碼。
- 少數模式覆蓋多數問題。
第 1 章總結
自測:能在 10 分鐘內對小問題做完 IPO → 分解 → 模式 嗎?能就前進。
➡️ 下一章:2 · 演算法設計