1. 项目概述
"PAT(Basic Level) Practice 1014 福尔摩斯的约会"是浙江大学计算机程序设计能力考试(Programming Ability Test,简称PAT)基础级题库中的一道经典编程题目。这道题以福尔摩斯探案为背景,要求考生通过分析字符串中的隐藏信息来破解约会时间,既考察了基础的字符串处理能力,又融入了趣味性的故事情节。
作为PAT考试中广为人知的"网红题",它经常被用作检验编程初学者字符串操作能力的试金石。题目将福尔摩斯和华生的经典探案场景与现代编程挑战巧妙结合,要求从给定的四行字符串中提取出星期、小时和分钟信息,最终输出标准化的约会时间格式。
2. 题目背景与需求解析
2.1 题目背景设定
题目设定福尔摩斯收到一张字条,上面写着:
"星期四 14:45"
但字条上的时间信息实际上是隐藏在四行字符串中的。我们需要编写程序从这些字符串中解码出正确的时间信息。
2.2 输入输出规范
输入格式:
程序需要处理四行输入:
- 前两行字符串包含星期和小时信息
- 后两行字符串包含分钟信息
输出格式:
程序应输出形如"DAY HH:MM"的字符串,其中:
- DAY是3个字母表示的星期几(大写)
- HH是24小时制的小时(两位数)
- MM是分钟(两位数)
2.3 核心解题思路
- 星期解码:在前两个字符串中寻找第一对相同的大写字母(A-G),对应星期一到星期日
- 小时解码:在星期字母之后的位置,继续寻找相同的字符(0-9或A-N),对应0-23小时
- 分钟解码:在后两个字符串中寻找第一对相同的字母字符(A-Z或a-z),位置索引对应分钟数
3. 关键技术实现细节
3.1 字符串遍历与字符匹配
python复制def find_common_char(str1, str2, condition):
for i in range(min(len(str1), len(str2))):
if str1[i] == str2[i] and condition(str1[i]):
return i, str1[i]
return -1, None
这个辅助函数实现了:
- 同时遍历两个字符串
- 检查相同位置的字符是否相同
- 通过condition函数进行条件过滤
- 返回匹配的位置和字符
3.2 星期信息解码
python复制# 星期解码条件:大写字母A-G
def is_weekday_char(c):
return c.isupper() and 'A' <= c <= 'G'
# 获取星期几
weekday_map = {
'A': 'MON',
'B': 'TUE',
'C': 'WED',
'D': 'THU',
'E': 'FRI',
'F': 'SAT',
'G': 'SUN'
}
_, day_char = find_common_char(s1, s2, is_weekday_char)
day = weekday_map[day_char]
关键点:
- 只匹配A-G的大写字母
- 使用字典映射到对应的星期缩写
- 注意只需要找第一对匹配的字符
3.3 小时信息解码
python复制# 小时解码条件:在星期字符之后,数字0-9或A-N
def is_hour_char(c, start_pos):
return c.isdigit() or ('A' <= c <= 'N')
# 获取小时
hour_pos, hour_char = find_common_char(s1[start_pos+1:], s2[start_pos+1:], is_hour_char)
if hour_char.isdigit():
hour = int(hour_char)
else:
hour = 10 + ord(hour_char) - ord('A')
注意事项:
- 搜索范围从星期字符之后开始
- 数字0-9直接转换为小时
- 字母A-N对应10-23小时
- 需要格式化为两位数输出
3.4 分钟信息解码
python复制# 分钟解码条件:字母字符
def is_minute_char(c):
return c.isalpha()
# 获取分钟
minute_pos, _ = find_common_char(s3, s4, is_minute_char)
minute = f"{minute_pos:02d}"
实现细节:
- 在后两个字符串中查找
- 任意字母字符都符合条件
- 字符的位置索引即为分钟数
- 需要格式化为两位数
4. 完整代码实现
python复制def solve():
s1 = input().strip()
s2 = input().strip()
s3 = input().strip()
s4 = input().strip()
# 辅助函数:查找满足条件的第一个相同字符
def find_common_char(str1, str2, condition):
for i in range(min(len(str1), len(str2))):
if str1[i] == str2[i] and condition(str1[i]):
return i, str1[i]
return -1, None
# 解码星期
weekday_map = {
'A': 'MON',
'B': 'TUE',
'C': 'WED',
'D': 'THU',
'E': 'FRI',
'F': 'SAT',
'G': 'SUN'
}
day_pos, day_char = find_common_char(s1, s2, lambda c: c.isupper() and 'A' <= c <= 'G')
day = weekday_map[day_char]
# 解码小时
hour_pos, hour_char = find_common_char(
s1[day_pos+1:],
s2[day_pos+1:],
lambda c: c.isdigit() or ('A' <= c <= 'N')
)
if hour_char.isdigit():
hour = int(hour_char)
else:
hour = 10 + ord(hour_char) - ord('A')
# 解码分钟
minute_pos, _ = find_common_char(s3, s4, lambda c: c.isalpha())
# 格式化输出
print(f"{day} {hour:02d}:{minute_pos:02d}")
solve()
5. 常见问题与调试技巧
5.1 边界条件处理
问题1:输入字符串长度不一致怎么办?
- 解决方案:遍历时使用min(len(str1), len(str2))作为上限,避免越界
问题2:找不到匹配字符怎么办?
- 题目保证有解,实际编程中可添加错误处理
5.2 典型错误分析
错误1:小时解码范围错误
- 症状:小时值超过23
- 原因:没有限制字母范围到N
- 修复:添加'A' <= c <= 'N'条件
错误2:分钟格式错误
- 症状:输出如"9:5"而不是"09:05"
- 原因:未格式化两位数
- 修复:使用f"{hour:02d}"格式
5.3 测试用例设计
建议测试用例:
-
常规情况:
输入:code复制3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hyscvnm输出:THU 14:04
-
边界情况:
输入:code复制AAAAAAAAAA AAAAAAAAAA a a输出:MON 00:00
-
最大小时测试:
输入:code复制GNX GNX z z输出:SUN 23:00
6. 性能优化与扩展思考
6.1 算法复杂度分析
- 时间复杂度:O(n),n为字符串长度
- 空间复杂度:O(1),只使用了常数空间
6.2 可能的扩展方向
- 错误处理增强:添加对非法输入的检测和处理
- 多语言支持:扩展星期显示为不同语言
- 日期计算:结合具体日期而不仅仅是星期
- 更复杂的编码规则:支持更丰富的时间表达方式
6.3 实际应用场景
这种字符串解析技术可应用于:
- 日志文件分析
- 数据清洗和提取
- 协议解码
- 自然语言处理中的模式匹配
这道题目虽然设定简单,但很好地训练了编程者处理字符串、条件判断和格式化输出的能力。在实际编程中,类似的字符串解析需求非常常见,掌握这些基础技能对任何开发者都至关重要。
