How to convert from Roman numeral to decimal

1 回表示 (過去 30 日間)
Madeleine
Madeleine 2015 年 1 月 22 日
編集済み: Stephen23 2015 年 1 月 23 日
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

採用された回答

Stephen23
Stephen23 2015 年 1 月 22 日
編集済み: Stephen23 2015 年 1 月 23 日
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 件のコメント
Stephen23
Stephen23 2015 年 1 月 23 日
編集済み: Stephen23 2015 年 1 月 23 日
@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.
Stephen23
Stephen23 2015 年 1 月 23 日
編集済み: Stephen23 2015 年 1 月 23 日
Or perhaps the best solution would be to start again, from a completely blank script, and test each line as you write it.

サインインしてコメントする。

その他の回答 (2 件)

Niels
Niels 2015 年 1 月 22 日
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 件のコメント
Madeleine
Madeleine 2015 年 1 月 22 日
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.

サインインしてコメントする。


Guillaume
Guillaume 2015 年 1 月 22 日
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.

カテゴリ

Help Center および File ExchangeFunction Creation についてさらに検索

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by