1 2 Previous Next 15 Replies Latest reply on Dec 11, 2007 7:50 PM by 807603

    I need help with converting Roman Numerals to Arabic numbers

    807603
      Hello everyone,

      I am taking an AP Computer Science A class and I am doing an assignment to make a program that converts Roman Numerals to Arabic numbers and the opposite. I got the Arabic to Roman part down perfectly, but the other way around is giving me trouble. Can anyone help me?

      Here's what I have so far, and the question I have is at the end.

      import java.io.*;

      public class RomanNumerals{

           public static void main (String [] args)
           {
                DataInput keyboard=new DataInputStream (System.in);
                String input;
                
                try
                {
                     //options
                     System.out.println("1. Roman numerals to Arabic numbers");
                     System.out.println("2. Arabic numbers to Roman numerals");
                     System.out.println("3. Exit");
                     System.out.print("Enter your option: ");
                     input=keyboard.readLine();
                     
                     int choice=Integer.parseInt(input);
                     
                     switch (choice)
                     {
                          //Roman numerals to Arabic numbers
                          case 1:
                               String romanInput, ro;
                               int answer1;
                               
                               System.out.print("Enter a Roman numeral: ");
                               romanInput=keyboard.readLine();
                               
                               ro=romanInput.toUpperCase();
                               
                               answer1=toArabic(ro);
                               
                               System.out.println("The Arabic number is: "+answer1);
                               break;
                          //Arabic numbers to Roman numerals
                          case 2:
                               String arabicInput, answer;
                               
                               System.out.print("Enter an Arabic number: ");
                               arabicInput=keyboard.readLine();
                               int arabic=Integer.parseInt(arabicInput);
                               
                               answer=toRomans(arabic);
                               System.out.println("The Roman numeral is: "+answer);
                               break;
                          case 3:
                               break;
                          default:
                               System.out.println("Invalid option.");
                     }
                }
                catch(IOException e)
                {
                     System.out.println("Error");
                }
                     //method to convert Arabic numbers to Roman numerals
           }
           public static String toRomans (int N)
           {
                String roman="";
                          
                while (N>=1000)
                {
                     roman+="M";
                     N-=1000;
                }
                while (N>=900)
                {
                     roman+="CM";
                     N-=900;
                }
                while (N>=500)
                {
                     roman+="D";
                     N-=500;
                }
                while (N>=400)
                {
                     roman+="CD";
                     N-=400;
                }
                while (N>=100)
                {
                     roman+="C";
                     N-=100;
                }
                while (N>=90)
                {
                     roman+="XC";
                     N-=90;
                }
                while (N>=50)
                {
                     roman+="L";
                     N-=50;
                }
                while (N>=40)
                {
                     roman+="XL";
                     N-=40;
                }
                while (N>=10)
                {
                     roman+="X";
                     N-=10;
                }
                while (N>=9)
                {
                     roman+="IX";
                     N-=9;
                }
                while (N>=5)
                {
                     roman+="V";
                     N-=5;
                }
                while (N>=4)
                {
                     roman+="IV";
                     N-=4;
                }
                while (N>=1)
                {
                     roman+="I";
                     N-=1;
                }
                
                return(roman);
           }
           
           //method to convert Roman numerals to Arabic numbers
           public static int toArabic (String x)
           {
                int arabica=0;
                char chars;
                
                for (int y=0; y<=(x.length()-1); y++)
                {
                     chars=x.charAt(y);
                     
                     switch (chars)
                     {
                          case 'C':
                               if (x.charAt(y+1)=='M')
                               {
                                    arabica+=900;
                                    y++;
                               }
                               else if (x.charAt(y+1)=='D')
                               {
                                    arabica+=400;
                                    y++;
                               }
                               else
                               {
                                    arabica+=100;
                               }
                               break;
                          case 'X':
                               if (x.charAt(y+1)=='C')
                               {
                                    arabica+=90;
                                    y++;
                               }
                               else if (x.charAt(y+1)=='L')
                               {
                                    arabica+=40;
                                    y++;
                               }
                               else
                               {
                                    arabica+=10;
                               }
                               break;
                          case 'I':
                               if (x.charAt(y+1)=='X')
                               {
                                    arabica+=9;
                                    y++;
                               }
                               else if (x.charAt(y+1)=='V')
                               {
                                    arabica+=4;
                                    y++;
                               }
                               else
                               {
                                    arabica++;
                               }
                               break;
                          case 'M':
                               arabica+=1000;
                               break;
                          case 'D':
                               arabica+=500;
                               break;
                          case 'L':
                               arabica+=50;
                               break;
                          case 'V':
                               arabica+=5;
                               break;
                     }
                }
                return(arabica);
           }
           }

      I have if-else statements made for each cases for Roman to Arabic. However, when I put the input as any single character C, X, and I, the program will not show a value. (Like if I put just X in, it should show me 10 but it says error. NOTE: single character does work for rest) I'm thinking that something is up with the "else" part of case C, case X, and case I that does not allow me to put in single characters for D, L, and V. What is a possible solution?

      Thanks
        • 1. Re: I need help with converting Roman Numerals to Arabic numbers
          807603
          Before delving too far into your code, I see you are walking forward through the string. As you've found out, this often means you have to look at the next character, which I think is causing problems for you.

          I suggest walking through the string backwards. Consider the string "MCMLXXXIV" (1984 if I typed that right). Walk through the string backwards, adding numbers if they were greater or equal to the last number you added, and subtract them when they're less than the last number. So for the given string, you'd have 5 - 1 + 10 + 10 + 10 + 50 + 1000 - 100 + 1000 = 1984.
          • 2. Re: I need help with converting Roman Numerals to Arabic numbers
            807603
            I thought about that, but my teacher didn't teach us at all about reading strings backwards, so how would I do that? Could you give me an example in regards to my code?

            Thanks
            • 3. Re: I need help with converting Roman Numerals to Arabic numbers
              807603
              for (int y=0; y<=(x.length()-1); y++)
              Change this for() loop to count down from the end of the string instead of up from the start of the string.
              • 4. Re: I need help with converting Roman Numerals to Arabic numbers
                807603
                before I start reworking on the code, just to make sure, would I change

                for (int y=0; y<=(x.length()-1); y++)

                this to

                for (int y=0; y>=(x.length()+1); y--)?

                Thanks
                • 5. Re: I need help with converting Roman Numerals to Arabic numbers
                  807603
                  Part way there, but you're still starting from 0. You need to start from the end, and test if you've reached the beginning.
                  • 6. Re: I need help with converting Roman Numerals to Arabic numbers
                    807603
                    for (int y=0; y>=(x.length()+1); y--)

                    I'm thinking that changing it so that the string gets counted from the end has something to do with the "int y=0" part. would this do it?

                    char c1 = charAt(x);
                    for(int y=c1; y>=(x.length()+1); y--)
                    • 7. Re: I need help with converting Roman Numerals to Arabic numbers
                      807603
                      jhong253 wrote:
                      for (int y=0; y>=(x.length()+1); y--)

                      I'm thinking that changing it so that the string gets counted from the end has something to do with the "int y=0" part. would this do it?

                      char c1 = charAt(x);
                      for(int y=c1; y>=(x.length()+1); y--)
                      A for loop has three parts:
                      for (INITIALIZATION; CONDITION; UPDATE)
                      Let's look at this:
                      for (int y=0; y<=(x.length()-1); y++)
                      The initialization is declaring an int y and setting it to 0. This is always done, and only done once.
                      The condition says that in order to execute the body of the loop, y must be less than or equal to (x.length() - 1).
                      The update says that after the loop body executes, y should be incremented

                      If you want to count backwards:
                      1. Initialize y to the ending index, x.length() - 1
                      2. You want to continue executing the loop while the index is still valid (hasn't progressed past the start of the string).
                      3. You want to decrement y every time the body executes.
                      • 8. Re: I need help with converting Roman Numerals to Arabic numbers
                        807603
                        Ok, I tried this after I read your reply:

                        for (int y=x.length()-1; y<=(x.length()-1); y++)
                                  {

                        Before this, when the program wouldn't give correct values to something like X, the program gave out 15 for XV. Now it's comes out with 5 for XV.
                        The thing is, this is the error my compiler gave out when I entered just X before I asked the question and it still gives out the same error.

                        Enter a Roman numeral: X
                        Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
                        at java.lang.String.charAt(String.java:687)
                        at RomanNumerals.toArabic(RomanNumerals.java:162)
                        at RomanNumerals.main(RomanNumerals.java:33)

                        What should I do? I know that the string is counted backwards now, but the error is still same.
                        • 9. Re: I need help with converting Roman Numerals to Arabic numbers
                          807603
                          jhong253 wrote:
                          Ok, I tried this after I read your reply:

                          for (int y=x.length()-1; y<=(x.length()-1); y++)
                          You need to study for loops; this is wrong. Write some for loops that just display the loop variable until you have a better understanding of how they work. This is fundamental, so you need to get it right.
                          • 10. Re: I need help with converting Roman Numerals to Arabic numbers
                            807603
                            oops sorry, I replied with the wrong thing.
                            The actual loop I had was this:

                            for (int y=x.length()-1; y>=(x.length()-1); y--)
                                      {

                            would this work?

                            Edited by: jhong253 on Dec 10, 2007 7:01 PM
                            • 11. Re: I need help with converting Roman Numerals to Arabic numbers
                              807603
                              jhong253 wrote:
                              for (int y=x.length()-1; y>=(x.length()-1); y--)
                                        {

                              would this work?
                              No. Stop guessing, and study for loops again.
                              • 12. Re: I need help with converting Roman Numerals to Arabic numbers
                                807603
                                no, i wasn't guessing.

                                When I tried it on the program with just the loop changed without rest of the methods changed at all, the program gave out this:

                                Enter a Roman numeral: XV
                                The Arabic number is: 5

                                Rest of switch cases hadn't changed, and the original had given out 15 for XV, so i thought

                                for (int y=x.length()-1; y>=(x.length()-1); y--)
                                          {

                                this was reading XV backwards.

                                So is this loop right?
                                • 13. Re: I need help with converting Roman Numerals to Arabic numbers
                                  807603
                                  jhong253 wrote:
                                  So is this loop right?
                                  No. Run through it on paper using the 1984 example.
                                  • 14. Re: I need help with converting Roman Numerals to Arabic numbers
                                    807603
                                    Ok, I ran the 1984 through my first code with my first loop, and it worked. The thing is, the old code doesn't work when I just put in one X; it says the string is out of range. I think it's because then it comes out as y, or 1 in beginning, is > 0, because one character minus 1 as it is in the loop is 0.
                                    But the thing is, take a look at my case V. When I just put in any cases without if statements, it works. But when i put in just X or I or any other cases with if statements involved, it doesn't. Any idea why?

                                    This is my switch statement,

                                    switch (chars)
                                                   {
                                                        case 'C':
                                                             if (x.charAt(y+1)=='M')
                                                             {
                                                                  arabica+=900;
                                                                  y++;
                                                             }
                                                             else if (x.charAt(y+1)=='D')
                                                             {
                                                                  arabica+=400;
                                                                  y++;
                                                             }
                                                             else
                                                             {
                                                                  arabica+=100;
                                                             }
                                                             break;
                                                        case 'X':
                                                             if (x.charAt(y+1)=='C')
                                                             {
                                                                  arabica+=90;
                                                                  y++;
                                                             }
                                                             else if (x.charAt(y+1)=='L')
                                                             {
                                                                  arabica+=40;
                                                                  y++;
                                                             }
                                                             else
                                                             {
                                                                  arabica+=10;
                                                             }
                                                             break;
                                                        case 'I':
                                                             if (x.charAt(y+1)=='X')
                                                             {
                                                                  arabica+=9;
                                                                  y++;
                                                             }
                                                             else if (x.charAt(y+1)=='V')
                                                             {
                                                                  arabica+=4;
                                                                  y++;
                                                             }
                                                             else
                                                             {
                                                                  arabica++;
                                                             }
                                                             break;
                                                        case 'M':
                                                             arabica+=1000;
                                                             break;
                                                        case 'D':
                                                             arabica+=500;
                                                             break;
                                                        case 'L':
                                                             arabica+=50;
                                                             break;
                                                        case 'V':
                                                             arabica+=5;
                                                             break;
                                    1 2 Previous Next