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

# Problem with a string method

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
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
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
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
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
``````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");

int choice=Integer.parseInt(input);

switch (choice)
{
//Roman numerals to Arabic numbers
case 1:
String romanInput, ro;

System.out.print("Enter a Roman numeral: ");

ro=romanInput.toUpperCase();

answer1=toArabic(ro); //line 33 where the error occurs

break;
//Arabic numbers to Roman numerals
case 2:

System.out.print("Enter an Arabic number: ");
int arabic=Integer.parseInt(arabicInput);

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
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
``````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");

int choice=Integer.parseInt(input);

switch (choice)
{
//Roman numerals to Arabic numbers
case 1:
String romanInput, ro;

System.out.print("Enter a Roman numeral: ");

ro=romanInput.toUpperCase();

answer1=toArabic(ro); //line 33 where the error occurs

break;
//Arabic numbers to Roman numerals
case 2:

System.out.print("Enter an Arabic number: ");
int arabic=Integer.parseInt(arabicInput);

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
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
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
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
substring() isn't what you want. Yes, the y++ is unnecessary in your x.length() == 1 blocks, but that whole block is wrong anyway.

``````if (y == (x.length() - 1))