01 - 编程思维训练¶
目标:重建独立思考和编码能力
时间:1-2周
核心原则:先思考,再编码;先手写,再验证
🧠 什么是编程思维?¶
编程思维不是"记住语法",而是: 1. 问题分解:把大问题拆成小问题 2. 模式识别:发现问题的共性 3. 抽象思维:提取关键逻辑,忽略细节 4. 算法思维:设计解决问题的步骤
示例:从生活到代码¶
生活问题:整理书架
编程问题:排序数组
Python
def sort_books(books):
# 1. 分类
categories = {}
for book in books:
cat = book.category
if cat not in categories:
categories[cat] = []
categories[cat].append(book)
# 2. 每类排序
for cat in categories:
categories[cat].sort(key=lambda b: b.author) # lambda匿名函数:简洁的单行函数
# 3. 合并
result = []
for cat in sorted(categories.keys()):
result.extend(categories[cat])
return result
核心:解决问题的思路是相通的!
🎯 训练方法¶
方法1:伪代码先行¶
规则:写代码之前,先用中文/英文写出解决步骤
练习1:找最大值¶
问题:给定一个数组,找出最大值
步骤1:写伪代码
步骤2:翻译成代码
Python
def find_max(arr):
if not arr:
return None
max_val = arr[0] # 假设第一个数是最大值
for num in arr: # 遍历数组
if num > max_val: # 如果当前数更大
max_val = num # 更新最大值
return max_val
练习2:判断回文¶
问题:判断一个字符串是否是回文(正读反读相同)
步骤1:写伪代码
步骤2:翻译成代码
Python
def is_palindrome(s):
left, right = 0, len(s) - 1
while left < right:
if s[left] != s[right]:
return False
left += 1
right -= 1
return True
方法2:画图辅助思考¶
规则:复杂问题,先画图理清逻辑
练习3:反转链表¶
问题:反转一个单链表
步骤1:画图
Text Only
原始链表:
1 -> 2 -> 3 -> 4 -> None
反转后:
None <- 1 <- 2 <- 3 <- 4
过程:
prev curr next
None 1 -> 2 -> 3 -> 4
Step1: curr.next = prev
None <- 1 2 -> 3 -> 4
Step2: 移动指针
prev curr next
1 -> 2 -> 3 -> 4
步骤2:写代码
Python
def reverse_list(head):
prev = None
curr = head
while curr:
next_temp = curr.next # 保存下一个节点
curr.next = prev # 反转指针
prev = curr # prev前移
curr = next_temp # curr前移
return prev
方法3:边界条件思维¶
规则:写代码时,先考虑边界情况
常见边界条件¶
Python
# 1. 空输入
def process(arr):
if not arr: # 空数组
return []
# ...
# 2. 单个元素
def process(arr):
if len(arr) == 1:
return arr[0]
# ...
# 3. 极端值
def divide(a, b):
if b == 0: # 除零
raise ValueError("Cannot divide by zero")
# ...
# 4. 类型检查
def process(data):
if not isinstance(data, list): # isinstance检查对象类型
raise TypeError("Expected list")
# ...
练习4:安全的数组访问¶
Python
def safe_get(arr, index):
"""安全地获取数组元素"""
# 边界检查
if not arr: # 空数组
return None
if index < 0 or index >= len(arr): # 索引越界
return None
return arr[index]
# 测试
print(safe_get([1, 2, 3], 1)) # 2
print(safe_get([1, 2, 3], 5)) # None
print(safe_get([], 0)) # None
print(safe_get([1, 2, 3], -1)) # None
📝 刻意练习¶
练习1:基础逻辑(1-3天)¶
要求:每个题目先写伪代码,再写代码
题目1:两数之和¶
给定一个数组和一个目标值,找出数组中和为目标值的两个数的索引。
Python
def two_sum(nums, target):
"""
伪代码:
1. 创建一个字典存储已遍历的数
2. 遍历数组:
计算 complement = target - 当前数
如果 complement 在字典中:
返回 [complement的索引, 当前索引]
将当前数加入字典
3. 如果没找到,返回空列表
"""
# 你的代码
pass
# 测试
two_sum([2, 7, 11, 15], 9) # 应该返回 [0, 1]
题目2:合并两个有序数组¶
将两个有序数组合并成一个有序数组。
Python
def merge_sorted(arr1, arr2):
"""
伪代码:
1. 创建结果数组
2. 用两个指针分别指向两个数组的开头
3. 比较指针所指元素,将较小的放入结果
4. 移动较小元素所在数组的指针
5. 重复直到一个数组遍历完
6. 将另一个数组剩余元素加入结果
"""
# 你的代码
pass
# 测试
merge_sorted([1, 3, 5], [2, 4, 6]) # [1, 2, 3, 4, 5, 6]
题目3:有效的括号¶
给定一个只包含括号的字符串,判断括号是否有效。
Python
def is_valid_parentheses(s):
"""
伪代码:
1. 用栈来存储左括号
2. 遍历字符串:
如果是左括号,入栈
如果是右括号:
如果栈为空,无效
弹出栈顶,检查是否匹配
3. 最后栈应该为空
"""
# 你的代码
pass
# 测试
is_valid_parentheses("()[]{}") # True
is_valid_parentheses("([)]") # False
练习2:数据处理(3-5天)¶
题目4:统计词频¶
给定一段文本,统计每个单词出现的次数。
Python
def word_frequency(text):
"""
伪代码:
1. 将文本转换为小写
2. 分割成单词列表
3. 用字典统计每个单词出现次数
4. 返回字典
"""
# 你的代码
pass
# 测试
text = "Hello world hello Python"
word_frequency(text) # {'hello': 2, 'world': 1, 'python': 1}
题目5:查找共同好友¶
给定两个字典表示用户的好友列表,找出共同好友。
Python
def common_friends(user1_friends, user2_friends):
"""
伪代码:
1. 将两个列表转换为集合
2. 求集合的交集
3. 返回交集列表
"""
# 你的代码
pass
# 测试
user1 = {"Alice": ["Bob", "Charlie", "David"]}
user2 = {"Bob": ["Alice", "Charlie", "Eve"]}
common_friends(user1["Alice"], user2["Bob"]) # ["Charlie"]
练习3:文件操作(5-7天)¶
题目6:CSV处理器¶
读取CSV文件,计算某列的平均值。
Python
def csv_average(filename, column_name):
"""
伪代码:
1. 打开CSV文件
2. 读取表头,找到目标列的索引
3. 遍历每一行,累加目标列的值
4. 计算平均值
5. 返回结果
"""
# 你的代码
pass
题目7:日志分析器¶
分析日志文件,统计每小时的访问次数。
Python
def analyze_log(log_file):
"""
伪代码:
1. 打开日志文件
2. 用正则提取时间戳
3. 按小时统计访问次数
4. 返回统计结果
"""
# 你的代码
pass
🔍 调试思维训练¶
调试步骤¶
Text Only
1. 复现问题
- 什么情况下出现bug?
- 能稳定复现吗?
2. 定位问题
- 用print输出中间结果
- 缩小问题范围
3. 分析问题
- 为什么会出现这个问题?
- 我的假设哪里错了?
4. 解决问题
- 修改代码
- 验证修复
5. 预防问题
- 为什么会犯这个错误?
- 下次如何避免?
练习8:找出bug¶
下面代码有bug,找出并修复:
Python
def find_duplicates(arr):
"""找出数组中的重复元素"""
duplicates = []
for i in range(len(arr)):
for j in range(i + 1, len(arr)):
if arr[i] == arr[j]:
duplicates.append(arr[i])
return duplicates
# 测试
print(find_duplicates([1, 2, 2, 3, 3, 3])) # 期望: [2, 3]
# 实际输出: [2, 3, 3] - 3出现了两次!
思考过程:
Text Only
1. 复现:输入[1,2,2,3,3,3],输出[2,3,3]
2. 定位:3被添加了两次
3. 分析:当i指向第一个3时,j会指向第二个和第三个3,导致重复添加
4. 解决:用set去重,或修改逻辑
5. 预防:考虑边界情况
修复:
Python
def find_duplicates(arr):
"""找出数组中的重复元素"""
seen = set()
duplicates = set()
for num in arr:
if num in seen:
duplicates.add(num)
seen.add(num)
return list(duplicates)
✅ 阶段检查¶
完成以下检查,确认你掌握了编程思维:
- 能不查资料,独立写出伪代码
- 能根据伪代码翻译成正确代码
- 能画出问题的逻辑流程图
- 能考虑边界条件
- 能独立调试简单bug
📚 下一步¶
完成编程思维训练后,进入 02-手写代码练习计划.md
记住:编程思维是内功,语法只是招式。内功深厚,招式自然流畅! 💪