
本文详解罗马数字转整数的标准算法逻辑,指出原始代码中索引误用、边界判断错误及减法规则应用混乱等问题,并提供简洁健壮的手写实现与第三方库方案。
本文详解罗马数字转整数的标准算法逻辑,指出原始代码中索引误用、边界判断错误及减法规则应用混乱等问题,并提供简洁健壮的手写实现与第三方库方案。
罗马数字由特定字符(I, V, X, L, C, D, M)按规则组合而成,其核心转换逻辑基于“左减右加”原则:当较小值字符出现在较大值字符左侧时(如 IV, IX, XL, XC, CD, CM),表示相减;否则累加。原始代码存在多个关键缺陷:
- 错误地通过 list(dic.keys()).index(s[i]) 动态计算 next_symbol,但 I 后并非总是 V 或 X(例如 MCMXCIV 中 C 后是 M,非 D 或 L),导致逻辑错乱;
- string.remove(i) 和 string.remove(i+1) 破坏遍历索引,引发越界或跳过字符;
- 边界条件 i < len(s) 永真(因 i 来自 range(len(s))),而 i == len(s) 永不成立,造成冗余分支。
✅ 正确解法应从左到右单次遍历,比较当前字符与下一字符的数值大小:
def romanToInt(s: str) -> int:
dic = {'I': 1, 'V': 5, 'X': 10, 'L': 50,
'C': 100, 'D': 500, 'M': 1000}
total = 0
i = 0
while i < len(s):
# 若存在下一字符,且当前值小于下一值 → 触发减法(如 IV)
if i + 1 < len(s) and dic[s[i]] < dic[s[i + 1]]:
total += dic[s[i + 1]] - dic[s[i]]
i += 2 # 跳过两个字符
else:
total += dic[s[i]]
i += 1
return total
# 测试
print(romanToInt("MCMXCIV")) # 输出:1994
? 关键要点:
- 不修改原字符串或索引列表,用 i 手动控制步进;
- 仅当 i+1 有效且 dic[s[i]] < dic[s[i+1]] 时执行减法,覆盖全部六种合法减法组合;
- 时间复杂度 O(n),空间复杂度 O(1),逻辑清晰、无副作用。
? 替代方案(生产环境推荐):
若项目允许依赖第三方库,可直接使用成熟可靠的 roman 模块(需先安装:pip install roman):
import roman
print(roman.fromRoman("MCMXCIV")) # 1994
该模块已全面覆盖边缘情况(如空字符串、非法字符校验、超大数值等),适合快速集成。但面试或学习场景中,手写上述双指针逻辑更能体现对规则本质的理解。务必避免硬编码字符顺序或动态索引推导——罗马数字的减法规则仅取决于相邻字符数值关系,而非字母位置。
文章来自机圈观察员网,发布者:,转载请注明出处:https://www.jqgcy.com/shoujipingce/127093.html