罗马数字转整数特殊情况处理及函数实现求助
解决罗马数字转整数的减法场景问题
嗨,我懂你的困扰——你现在的代码只是把每个罗马符号的数值直接累加,但完全没处理那些小值符号放在大值符号左边的减法规则,比如IV应该是4而不是6,IX是9而不是11这类情况。
罗马数字的核心规则其实是这样的:
- 通常情况下,大值符号在前,直接累加数值(比如
VI是5+1=6,XII是10+1+1=12) - 当小值符号出现在大值符号左侧时,需要用大值减去小值(比如
IV=5-1=4,XL=50-10=40,CM=1000-100=900)
下面给你两种可行的解决方案,第一种是更高效的遍历判断法:
方法一:遍历比较相邻字符
我们可以先创建一个罗马符号到数值的映射字典,然后遍历字符串时,比较当前字符和下一个字符的数值:如果当前数值小于下一个,就减去当前值;否则就加上当前值。最后一个字符直接累加即可。
def FromRoman(string): # 建立罗马符号到整数的映射 roman_to_int = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000} total = 0 str_length = len(string) for i in range(str_length): # 不是最后一个字符,且当前值小于下一个值时,做减法 if i < str_length - 1 and roman_to_int[string[i]] < roman_to_int[string[i+1]]: total -= roman_to_int[string[i]] else: total += roman_to_int[string[i]] return total
测试例子
- 输入
'IV':第一个字符I(1)小于V(5),所以total -=1,然后第二个字符V直接加5,最终-1+5=4,正确。 - 输入
'MCMXCIV':遍历后计算为1000 -100 +1000 -10 +100 -1 +5 = 1994,完全符合预期。
方法二:替换特殊组合后累加
如果你觉得遍历判断的逻辑有点绕,也可以先把所有减法组合(比如IV、IX)替换成对应的数值字符串,再进行累加:
def FromRoman(string): # 先替换所有减法特殊组合 special_cases = {'IV': '4', 'IX': '9', 'XL': '40', 'XC': '90', 'CD': '400', 'CM': '900'} for combo, num_str in special_cases.items(): string = string.replace(combo, num_str) # 普通罗马符号的映射 roman_map = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000} total = 0 for char in string: if char.isdigit(): total += int(char) else: total += roman_map[char] return total
这种方法逻辑更直观,但需要额外的字符串替换操作,性能上比第一种稍差一点,不过对于常规的罗马数字输入来说完全够用。
你可以根据自己的习惯选择其中一种,测试几个特殊案例就能验证效果啦。
内容的提问来源于stack exchange,提问作者CaribbeanCool




