为何代码输出不符预期?break失效与非法字符未触发ERROR问题
石头剪刀布游戏代码错误分析与修复
问题描述:将当前代码运行输出为:
DRAW A WINS A WINS ERROR,而非预期的DRAW A WINS ERROR ERROR。请问为何当strB为'SRTR'(含非法字符'T')时,break语句未生效,且未将result设置为'ERROR'?
原代码如下:
def RockPaperScissors(strA,strB): A_win = 0 B_win = 0 allowed_letters = 'SRP' if (len(strA) != len(strB)): result = 'ERROR' elif (len(strA) == len(strB)): for char in strA: for c in strB: if char not in allowed_letters: result = 'ERROR' break elif c not in allowed_letters: result = 'ERROR' break for i in range(0,len(strA)): if (strA[i] == 'R' and strB[i] == 'S'): a_win = 1 A_win += a_win if (strA[i] == 'S' and strB[i] == 'P'): a_win = 1 A_win += a_win if (strA[i] == 'P' and strB[i] == 'R'): a_win = 1 A_win += a_win if (strB[i] == 'R' and strA[i] == 'S'): b_win = 1 B_win += b_win if (strB[i] == 'S' and strA[i] == 'P'): b_win = 1 B_win += b_win if (strB[i] == 'P' and strA[i] == 'R'): b_win = 1 B_win += b_win if A_win > B_win: result = 'A WINS' if B_win > A_win: result = 'B WINS' if A_win == B_win: result = 'DRAW' return result print(RockPaperScissors('RP','PR')) print(RockPaperScissors('PPP','RRR')) print(RockPaperScissors('RPSR','SRTR')) print(RockPaperScissors('RPS','RPSRP'))
问题根源拆解
1. 嵌套循环的break仅跳出内层循环,无法终止错误检测
你写的嵌套循环for char in strA套for c in strB完全不符合需求:它会把strA的每一个字符和strB的每一个字符都检查一遍,而非对应位置的字符对。更关键的是,当检测到非法字符时,break只能跳出内层的for c in strB循环,外层的for char in strA还会继续执行,错误检测逻辑根本没起到终止作用。
2. 错误标记后未提前终止函数,result被后续代码覆盖
就算错误检测逻辑正确设置了result='ERROR',后面的胜负计算循环还是会照常运行,计算出A_win和B_win的值后,会根据胜负结果重新给result赋值,直接覆盖了之前的ERROR。这就是为什么strB='SRTR'时,你得到的是A WINS而不是预期的ERROR。
3. 字符检查逻辑完全错误
游戏逻辑是每回合对应位置的字符对决,你不需要把两个字符串的所有字符两两配对检查,只需要逐个检查对应位置的字符是否合法即可(比如第1位的strA[0]和strB[0],第2位的strA[1]和strB[1])。
修复后的代码
def RockPaperScissors(strA, strB): A_win = 0 B_win = 0 allowed_letters = 'SRP' # 第一步:检查长度是否一致,不一致直接返回ERROR if len(strA) != len(strB): return 'ERROR' # 第二步:检查对应位置的字符是否合法,发现非法字符立即返回ERROR for a_char, b_char in zip(strA, strB): if a_char not in allowed_letters or b_char not in allowed_letters: return 'ERROR' # 第三步:计算胜负情况 for a_char, b_char in zip(strA, strB): # 判断A获胜的三种情况 if (a_char == 'R' and b_char == 'S') or \ (a_char == 'S' and b_char == 'P') or \ (a_char == 'P' and b_char == 'R'): A_win += 1 # 判断B获胜的三种情况 elif (b_char == 'R' and a_char == 'S') or \ (b_char == 'S' and a_char == 'P') or \ (b_char == 'P' and a_char == 'R'): B_win += 1 # 第四步:确定最终结果 if A_win > B_win: return 'A WINS' elif B_win > A_win: return 'B WINS' else: return 'DRAW' # 测试用例 print(RockPaperScissors('RP','PR')) # 输出: DRAW print(RockPaperScissors('PPP','RRR')) # 输出: A WINS print(RockPaperScissors('RPSR','SRTR')) # 输出: ERROR print(RockPaperScissors('RPS','RPSRP')) # 输出: ERROR
修复说明
- 提前终止逻辑:一旦检测到长度不匹配或非法字符,直接
return 'ERROR',彻底避免后续代码覆盖结果 - 对应位置检查:用
zip函数遍历两个字符串的对应字符对,完全符合游戏的回合对决逻辑 - 简化胜负判断:用
or合并相同逻辑的条件,减少重复代码,提升可读性
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

