CS50 Vanity Plates作业代码优化咨询:如何提升效率与简洁性
优化CS50 Vanity Plates验证代码
首先先修正原代码里的一个隐性bug:check_firstnum函数中的char != 0是类型错误,应该改为char != '0'——因为char是字符串类型,和整数0比较逻辑不严谨,虽当前运行结果可能巧合正确,但属于代码隐患。
下面给出两种优化方向的方案,兼顾可读性和效率:
方案1:简化逻辑,合并检查步骤
将所有验证规则整合到单个函数中,遍历一次即可完成所有检查,避免额外的函数调用和索引查找开销:
def main(): plate = input("Plate: ") print("Valid" if is_valid(plate) else "Invalid") def is_valid(plate): # 基础规则:长度2-6、开头两个字母、仅含字母数字 if not (2 <= len(plate) <= 6) or not plate[:2].isalpha() or not plate.isalnum(): return False # 数字规则:第一个数字不能为0,且数字出现后后续必须全是数字 has_seen_digit = False for char in plate: if char.isdigit(): if not has_seen_digit: # 首次出现数字不能是0 if char == '0': return False has_seen_digit = True else: # 已经出现过数字的情况下,不能再出现字母 if has_seen_digit: return False return True main()
优化点说明:
- 用
has_seen_digit标记是否已遇到数字,遍历一次完成所有数字规则检查,时间复杂度从原代码的O(n²)降到O(n) - 不符合条件时立即返回
False,无需继续遍历,提升执行效率 - 所有验证逻辑集中在一个函数,可读性更强,减少函数调用开销
方案2:使用正则表达式(极致简洁)
如果允许使用正则表达式,可通过一行正则匹配所有规则,代码极度紧凑:
import re def main(): plate = input("Plate: ") # 正则匹配规则:开头两个字母,后续要么全是字母,要么是字母+首非0数字+任意数字,且总长度2-6 if re.fullmatch(r'^[A-Za-z]{2}(?:[A-Za-z]*|[A-Za-z]*[1-9][0-9]*)$', plate) and 2 <= len(plate) <= 6: print("Valid") else: print("Invalid") main()
正则规则拆解:
^[A-Za-z]{2}:强制开头为两个字母(?:[A-Za-z]*|[A-Za-z]*[1-9][0-9]*):两种合法情况——要么后续全是字母,要么后续包含字母+第一个非0数字+任意数量数字re.fullmatch确保整个字符串完全符合规则
内容的提问来源于stack exchange,提问作者Dansyar
相关产品推荐
相关产品推荐

