首页 > 解决方案 > Octave/MATLAB 函数将罗马数字转换为十进制数

问题描述

我正在尝试在 Octave 中编写一个函数来将罗马数字转换为十进制数字。

到目前为止,我有两个主要问题:

1) 它只适用于长度不超过 6 个字母的罗马数字

2)只有当每个字母都小于前一个时,答案才是正确的。即它不会正确计算 (IV) 为 4,而是错误地计算为 6。

我需要以某种方式解决这两个问题。我强烈怀疑我解决问题的方法是错误的,并且有一种更有效的方法可以做到这一点。

无论如何,如果您对问题感兴趣和/或您知道解决此问题的好方法,我们将不胜感激任何帮助。

function roman2num(s)

  decimal = [1000, 500, 100, 50, 10, 5, 1];
  roman = ["M", "D", "C", "L", "X", "V", "I"];

  num = 0;

  for i = 1:7
    if strcmp(s(1), roman(i))
      num += decimal(i);
      break 
    end
  end

      if length(s) >= 2
      for i = 1:7
        if strcmp(s(2), roman(i))
          num += decimal(i);
          break 
        end
      end
   end

    if length(s) >= 3
      for i = 1:7
        if strcmp(s(3), roman(i))
          num += decimal(i);
          break 
        end
      end
   end

    if length(s) >= 4
      for i = 1:7
        if strcmp(s(4), roman(i))
          num += decimal(i);
          break 
        end
      end
   end

    if length(s) >= 5
      for i = 1:7
        if strcmp(s(5), roman(i))
          num += decimal(i);
          break 
        end
      end
   end

    if length(s) >= 6
      for i = 1:7
        if strcmp(s(6), roman(i))
          num += decimal(i);
          break 
        end
      end
   end

  num

end

标签: matlabloopsif-statementoctaveroman-numerals

解决方案


据我所知,您需要担心的唯一规则是确定该字母是否构成“加法”或“减法”操作。对于某些字母,只有在右边第一个不相等的字母代表更大的值时,我们才减去它。

例如,在两个's'IIV'右侧的第一个不相等的字母is所以我们减去 2 并为 the 加上 5,因为它的右侧没有字母。IVV

在 MATLAB 中实现此规则相当简单。

function num = roman2num(s)
    decimal = [1000, 500, 100, 50, 10, 5, 1];
    roman = ['M', 'D', 'C', 'L', 'X', 'V', 'I'];
    tokens = arrayfun(@(x) decimal(find(roman==x,1)), char(s));
    num = tokens(end);
    for idx = 1:numel(tokens)-1
        val = tokens(idx);
        ridx = find(tokens(idx+1:end) ~= val, 1);
        if ~isempty(ridx) && tokens(ridx + idx) > val
            num = num - val;
        else
            num = num + val;
        end
    end

我使用 1 到 3333 之间的所有数字进行了测试。


推荐阅读