Octave罗马数字转十进制函数求助:修复长度限制与计算错误
解决罗马数字转十进制的Octave函数问题
嘿,我来帮你搞定这个罗马数字转十进制的问题!你的原代码确实遇到了两个典型的问题,咱们一步步拆解并修复它。
原代码的核心问题分析
- 硬编码长度限制:你通过一堆
if length(s) >= N的判断来处理前6位,这不仅代码冗余,还直接限制了只能处理6位以内的罗马数字,完全没必要。 - 未处理减法规则:罗马数字里有特殊组合,比如
IV(4)、IX(9)这类小值字符在大值字符前的情况,需要用大值减小值,而你的代码只是简单相加,自然会算错。
更高效的实现思路
正确的罗马数字转换逻辑应该遵循:
- 先建立一个字符-数值的快速映射表,避免每次循环查找的低效操作;
- 遍历字符串时,对比当前字符和下一个字符的数值:
- 如果当前值 < 下一个值,就减去当前值;
- 否则就加上当前值;
- 这种方式自动支持任意长度的罗马数字,时间复杂度是O(n)(n为字符串长度),非常高效。
修复后的Octave代码
function num = roman2num(s) % 创建罗马字符到十进制数的映射表,快速查找 roman_map = containers.Map(... {'M', 'D', 'C', 'L', 'X', 'V', 'I'}, ... [1000, 500, 100, 50, 10, 5, 1]); num = 0; str_len = length(s); for i = 1:str_len current_val = roman_map(s(i)); % 判断是否需要应用减法规则 if i < str_len && current_val < roman_map(s(i+1)) num -= current_val; else num += current_val; end end end
代码说明与测试
- 用
containers.Map实现O(1)时间的字符查找,比原代码循环7次高效得多; - 自动适配任意长度的罗马数字,比如
"MMMCMXCIX"(3999)这种长字符串也能正确计算; - 完美处理减法组合,比如:
roman2num("IV") % 返回4 roman2num("IX") % 返回9 roman2num("MCMXCIV") % 返回1994 roman2num("XII") % 返回12
内容的提问来源于stack exchange,提问作者rustybandit
相关产品推荐
相关产品推荐

