MATLAB Answers

0

How to convert from Roman numeral to decimal

Asked by Madeleine on 22 Jan 2015
Latest activity Edited by Stephen Cobeldick on 23 Jan 2015
Here is the code I've devised, but the answer always comes out to 0. Any guidance would be much appreciated.
function [x]=roman2decimal(s)
s1=substring(s,1,1);
s2=substring(s,2,2);
s=substring(s,3,numel(s));
%case 1: 2 roman numbers;
numbers1=[4 9 40 90 400 900];
letters1=['I' 'I' 'X' 'X' 'C' 'C'];
letters2=['V' 'X' 'L' 'C' 'D' 'M'];
%if case 1 fails, we have case 2
numbers3=[ 1 5 10 50 100 500 1000];
letters3=['I' 'V' 'X' 'L' 'C' 'D' 'M'];
x=0;
s1=substring(s,1,1), s2=substring(s,2,2), s=substring(s,3,numel(s));
while (s~='')
case1=false;
case2=false;
i = 1;
while(i<=numel(numbers1) &~case1)
if (strcmp(s1,letters1(i)) & strcmp(s2,letters2(i)))
case1=true
x = x+numbers1(i) %update x
end
end
if(case1) %update s1, s2, s by advancing 2 characters to the right
s1=substring(s,1,1), s2=substring(s,2,2), s=substring(s,3,length(s))
else % case2
while(i<= numel(numbers3) & ~case2)
if (strcmp(s1,letters3(i))) %case2 applies % 1 letter match
case2=true
x = x+numbers3(i)%update x
end % if
end
end % if(case1)
if(case2), %update s1, s2, s by advancing 1 character to the right
s1=s2;
s2=substring(s,1,1),
s=substring(s,2,length(s));
if(~case1 && ~case2) error('Incorrect roman numeral')
end
end
end
% function [c]=substring(s,pos1,pos2)
% if(pos1 >=1 & pos2 >= pos1 & pos2 <= numel(s)) c=s(pos1:pos2);
% else c='';
% end
% end % substring

  0 Comments

Sign in to comment.

Tags

3 Answers

Answer by Stephen Cobeldick on 22 Jan 2015
Edited by Stephen Cobeldick on 23 Jan 2015
 Accepted Answer

There are multiple issues with this code. Here are a few points that need to be addressed:
  • The function substring is obsolete. Use matrix indexing instead. (I used the substring defined at the bottom of your code).
  • Using i as a variable name, as this is the name of the inbuilt imaginary unit . For the same reason, avoid j too.
  • Unused calculations and variables (e.g. lines three and four).
  • while loops with undefined end points... so they go into an infinite loop.
  • Poor formatting: by default MATLAB indents the code within loops and if statements by four spaces. Please use this, it makes your code much easier to follow.
  • Multiple assignments or operations on one line (e.g. lines eighteen and thirty-two). Put each of these on its own line, it is clearer and makes mistakes more obvious.
The solution to your problem is easy: Do not write a huge amount of untested code, run it, and then be surprised that it does not work. Programs are iterative processes, and you should never write everything in one go: write and test each line as you write it. Check that it makes sense, and that it gives the answer that you need it to. Then move on to the next line. It does not matter what you think the code should be doing, only what it really is doing.
If you had done this you would realize that you repeat the block of three substring operations with the result that by line twenty two-thirds of your input data has been replaced by empty strings. So you just threw away your data. How do I know this? In one word: debugging.
You need to learn about debugging . Yes it is complicated learning new things, but this will make your life easier, and your code two million times better.
To get you started, try this:
  • Open your code in the MATLAB Editor.
  • Look at the left-hand side of the editor. Some of the line-numbers also have a small hyphen symbol: these are lines with executable code.
  • Left-click on one of these lines (say, the one on line three) so that it becomes a little red circle. This sets a "breakpoint" in your code.
  • Now run your function normally (e.g. call the function from the command line).
  • The code will stop at the breakpoint, and you can see in the workspace all of the variables in the function's workspace. You can view these variables, and use the command window too for running any operations that you wish.
  • Press the f10 button on your keyboard, or the "Step" button on the MATLAB ribbon. This will run the line of code that the program is stopped at.
  • Keep using f10 (and try the other controls!) to see how your program changes with each line of your code.
Then you can see where and why it is not doing what you think it should be doing.
Have fun!

  4 Comments

Show 1 older comment
Madeleine,
I suggest you go back to my answer and actually use the debugger. You'll quickly find what is wrong with your code.
You're probably getting 0 because you're testing with a string of less than 3 characters. If you test with a longer string, you'll get an error because you've incorrectly modified your inner while loops.
You're also getting 0 because you've still not taken care of the end condition of the outer while loop. You're never processing the last two characters of your string. Use the debugger and you'll see why.
@Madeleine: Two people saying "use the debugger" is not enough? What can we write to convince you? As soon as you start using the debugger you will immediately find multiple points in your code that are not doing what you think they are doing. Use it.
Or perhaps the best solution would be to start again, from a completely blank script, and test each line as you write it.

Sign in to comment.


Answer by Niels
on 22 Jan 2015

The easiest solution is to get yourself a suitable tool from the File Exchange.
For example this tool by François Beauducel seems to do what you are looking for.
It is a pretty short and straightforward code as well, so looking into it a bit may also give you some ideas on ways to approach your problem if you are (for whatever reason) not able to use the mentioned tool.

  1 Comment

Hi Niels, Thank you for your reply. However, this is an assignment in "parallel arrays" for a course I'm taking and so those must be included.

Sign in to comment.


Answer by Guillaume
on 22 Jan 2015

The best way to help you is to tell you to learn how to use the debugger. Your code is nearly there but there are some very simple mistakes that you would have caught straight away had you stepped through the code.
So set a breakpoint on the first line of your code. Call your function and step through it line by line. You'll quickly see that:
- the condition of your first while loop is wrong. For a start it should be
~strcmp(s, '')
but also you stop it too early and will never process the last two characters of your input. You need to change the point at which you modify s
- you never increment i in your other two while loops, hence they run forever
- you never reset case1 and case2 to false.
The last two bugs are trivial to fix, the only one that is a bit trickier is getting the end condition of you main while loop correct. Fix that one, and your code works. You can then come back here and I'll show you how to make it more efficient.

  0 Comments

Sign in to comment.