12 Replies Latest reply: Dec 13, 2007 6:10 PM by 807603 RSS

    Problem with a string method

    807603
      Hello, I am working on a program that converts Roman numerals to Arabic numbers and the opposite. I have the Arabic to Roman part down, yet Roman to Arabic part is causing troubles for me.

      I know that there are many solutions out there, yet I would like just solutions within my code that would fix the problem it has.

      Instead of the whole code, here's the method that changes Roman to Arabic.

           //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.length() == 1)
                               {
                                    arabica+=100;
                                    y++;
                               }
                               else 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.length() == 1)
                               {
                                    arabica+=10;
                                    y++;
                               }
                               else 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.length() == 1)
                               {
                                    arabica+=1;
                                    y++;
                               }
                               else 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;
                     }
                }

      There's a problem with this, however, is that whenever I put something in like XX, CC, XXX, or II, the program says

      Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 2
      at java.lang.String.charAt(String.java:687)
      at RomanNumerals.toArabic(RomanNumerals.java:172)
      at RomanNumerals.main(RomanNumerals.java:33)

      I think this problem is caused by the if-else and else-if statements in my method for cases C, X, and I, as this problem doesn't come up when I do similar things to cases without the if statements. Could you perhaps find out what is causing this problem? I've been working on it for days after finishing the rest and I can't figure it out.

      Thanks
        • 1. Re: Problem with a string method
          807603
          I told you in the other thread you should read the string backwards to avoid having to deal with this problem. If you read it forward, you have to read ahead, which means you also need to check the string length before doing so (which is why you're having problems now).
          • 2. Re: Problem with a string method
            807603
            as I've told you, I've already done that. now, I would like to figure out a solution reading it forward
            • 3. Re: Problem with a string method
              807603
              It's much easier to read if you tag your code (highlight and click the CODE button). Also, put a comment on line 687, ie where it breaks. Will have another look when that's done :)
              • 4. Re: Problem with a string method
                807603
                jhong253 wrote:
                as I've told you, I've already done that. now, I would like to figure out a solution reading it forward
                See:
                If you read it forward, you have to read ahead, which means you also need to check the string length before doing so (which is why you're having problems now).
                • 5. Re: Problem with a string method
                  807603
                  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); //line 33 where the error occurs
                                            
                                            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.length() == 1)
                                            {
                                                 arabica+=100;
                                                 y++;
                                            }
                                            else 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.length() == 1)
                                            {
                                                 arabica+=10;
                                                 y++;
                                            }
                                            else if (x.charAt(y+1)=='C')   //the line 172 where error occurs
                                            {
                                                 arabica+=90;
                                                 y++;
                                            }
                                            else if (x.charAt(y+1)=='L')
                                            {
                                                 arabica+=40;
                                                 y++;
                                            }
                                            else
                                            {
                                                 arabica+=10;
                                            }
                                            break;
                                       case 'I':
                                            if(x.length() == 1)
                                            {
                                                 arabica+=1;
                                                 y++;
                                            }
                                            else 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);
                        }
                        }
                  When I put in XX as the input, this is what the error comes out as:
                  Enter a Roman numeral: XX
                  Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 2
                      at java.lang.String.charAt(String.java:687)
                      at RomanNumerals.toArabic(RomanNumerals.java:172)
                      at RomanNumerals.main(RomanNumerals.java:33)
                  • 6. Re: Problem with a string method
                    807603
                    You need to be focusing on the blocks that look like this:
                    if( x.length() == 1)
                    {
                      arabica+=100;
                      y++;
                    }
                    You've obviously run into the problem of when you enter one character, checking the next character runs into an error throws a StringIndexOutOfBoundsException. But what if you enter two characters? Or three characters? What you should really be checking is if you're currently at the last character:
                    if (y == (x.length() - 1))
                    {
                      arabica += somevaluehere;
                    }
                    Edited by: paul.miner on Dec 13, 2007 6:09 PM
                    • 7. Re: Problem with a string method
                      807603
                      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); //line 33 where the error occurs
                                                
                                                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.length() == 1)
                                                {
                                                     arabica+=100;
                                                     y++;
                                                }
                                                else 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.length() == 1)
                                                {
                                                     arabica+=10;
                                                     y++;
                                                }
                                                else if (x.charAt(y+1)=='C')   //the line 172 where error occurs
                                                {
                                                     arabica+=90;
                                                     y++;
                                                }
                                                else if (x.charAt(y+1)=='L')
                                                {
                                                     arabica+=40;
                                                     y++;
                                                }
                                                else
                                                {
                                                     arabica+=10;
                                                }
                                                break;
                                           case 'I':
                                                if(x.length() == 1)
                                                {
                                                     arabica+=1;
                                                     y++;
                                                }
                                                else 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);
                            }
                            }
                      When I put in XX as the input, this is what the error comes out as:
                      Enter a Roman numeral: XX
                      Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 2
                          at java.lang.String.charAt(String.java:687)
                          at RomanNumerals.toArabic(RomanNumerals.java:172)
                          at RomanNumerals.main(RomanNumerals.java:33)
                      • 8. Re: Problem with a string method
                        807603
                        You're always comparing with the original string length, not the length at which you are when comparing. The y++ also seems off when doing single chars, as you're increasing it in the loop anyway. You either need to compare against x.substring(y), or go backwards as paul.miner suggested.
                        • 9. Re: Problem with a string method
                          807603
                          Like when you say I need to compare againtst x.substring(y), do you mean I need to change, for example,

                          this:
                          else if (x.charAt(y+1)=='M')
                          to
                          else if (x.substring(y)=='M')
                          ?

                          What about the y++, are you saying that I should take those off whenever I say
                          if( x.length() == 1)
                                                    {
                          ?

                          Thanks
                          • 10. Re: Problem with a string method
                            807603
                            This
                            if( x.length() == 1)
                            fails on the second iteration for XX, because x is always of length 2. Therefore, x.charAt(y+1) gets executed and is out of bounds. So you'd need to check the length of the remaing substring.
                            At a quick glance the y++ probably doesn't matter but looks like it isn't needed.

                            Edited by: Brynjar on Dec 13, 2007 4:27 PM
                            • 11. Re: Problem with a string method
                              807603
                              substring() isn't what you want. Yes, the y++ is unnecessary in your x.length() == 1 blocks, but that whole block is wrong anyway.

                              I'm guessing you missed reply #6 due to your double-post...
                              • 12. Re: Problem with a string method
                                807603
                                ok, thanks for those informations Brynjar and paul.miner. I had the going-backwards thing worked out with my teacher, but I decided that since I started out going forwards, I just wanted to finish that way. Now I think I figured out what was wrong with it. I can't believe I didn't even think about doing that.
                                if (y == (x.length() - 1))
                                                         {
                                                           arabica += 100;
                                                         }
                                Anyways, thanks guys and 5 duke stars for each of you.