rustybandit
rustybandit

Reputation: 65

Octave/MATLAB Function to Convert Roman Numeral Into Decimal Number

I'm trying to write a function in Octave to convert roman numerals into decimal numbers.

What I have so far has two major problems:

1) It will only work for roman numerals up to 6 letters in length

2) The answer is only correct if each letter is smaller than the previous. ie it will not compute (IV) correctly as 4, but incorrectly as 6.

I need to somehow fix both of these problems. I have a strong suspicion that my approach to the problem is wrong and that there is an altogether more efficient way of doing this.

Anyway, if the problem interests you and/or you know of a good way to do this, any help is much appreciated.

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

Upvotes: 3

Views: 407

Answers (1)

jodag
jodag

Reputation: 22274

As far as I can tell the only rule you need to worry about is determining if the letter constitutes an "add" or "subtract" operation. For some letter, we only subtract it if the first non-equal letter to the right represents a greater value.

For example in 'IIV' The first non-equal letter to the right of both I's is V so we subtract 2 and add 5 for the V since it has no letters to the right.

Implementing this rule in MATLAB is fairly straightforward.

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

I tested using all the numerals between 1 and 3333.

Upvotes: 5

Related Questions