-1

this is probably a really simple problem, but I can't figure out where I went wrong. This is a homework problem, but I've worked through the logic, I just seem to be missing a small detail with my syntax or something, and it's causing issues.

import java.util.*;

public class RomanNumeral{
    private String romanInput;
    private int decimalValue;
    public boolean check;
    private int tester;
    private static final Hashtable<Character, Integer> converter = new Hashtable<Character, Integer>();{
    RomanNumeral.converter.put('I',1);
    RomanNumeral.converter.put('V',5);
    RomanNumeral.converter.put('X',10);
    RomanNumeral.converter.put('L',50);
    RomanNumeral.converter.put('C',100);
    RomanNumeral.converter.put('D',500);
    RomanNumeral.converter.put('M',1000);
    }

    public RomanNumeral(String romanInput){
    this.romanInput = romanInput;
    }

    /**
     * @return the roman numeral
     */
    public String getRoman() {
        convertRoman(romanInput);
        return romanInput;
    }

    /**
     * @return the decimal form of the numeral
     */
    public int getDecimal() {
        convertRoman(romanInput);
        return decimalValue;
    }

    private void isValid(String romanInput){
        tester=0;
        for(int i = 0; i < romanInput.length(); i++) { //this test detects invalid characters
            char letter = romanInput.charAt(i);
            if(converter.containsKey(letter)){
                tester += 1;
            }
            else {
            }
        }
        check = (tester==romanInput.length());

    }

    //go character by character to convert the number (converter.lookup() would be better, but requires all cases be present in the Hash table (as far as I know))
    private void convertRoman(String romanInput){
        isValid(romanInput);
        if(check){
            decimalValue = 0;
            for(int i = 0; i < romanInput.length(); i++) {
                char letter = romanInput.charAt(i);
                int n = (int) converter.get(letter);
                if(i < romanInput.length()){
                    if(n < ((int)converter.get(romanInput.charAt(i+1)))){
                        decimalValue -= n;
                    }
                    else {
                        decimalValue += n;
                    }
                }
                else {
                    decimalValue += n;
                }
            }
        }
        else{
            decimalValue = 0;
            this.romanInput = "Invalid Roman Numeral";
        }
    }
}

When I run this code using getRoman("IV") or any other roman numeral, I get the following:

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
    at java.lang.String.charAt(Unknown Source)
    at RomanNumeral.convertRoman(RomanNumeral.java:61)
    at RomanNumeral.getRoman(RomanNumeral.java:26)

Could I get a pointer as to what's wrong? I remembered to limit my index to the length of the string, not sure what I'm missing.

EDIT: I recognize that my stack trace points to line 61. I already made the line before check to make sure that i is less than the length of the string I'm indexing. What else can I check to make this work?

ividito
  • 321
  • 3
  • 14
  • 1
    possible duplicate of [What is a stack trace, and how can I use it to debug my application errors?](http://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors) – ben75 Mar 12 '15 at 21:24
  • Add some `println`s to your code. You'll figure it out eventually. – Azar Mar 12 '15 at 21:25
  • Arrays in java are Zero based. – Jens Mar 12 '15 at 21:25

2 Answers2

1

Here is your problem:

for(int i = 0; i < romanInput.length(); i++) {
   ...
   if(i < romanInput.length()){
       if(n < ((int)converter.get(romanInput.charAt(i+1)))){
           decimalValue -= n;
       }

You try to access romanInput.charAt(i+1) but this index might not exist as you ensured only i < romanInput.length(). I think you need rather something like

for(int i = 0; i < romanInput.length(); i++) {
   ...
    if(i < romanInput.length() -1){ // here -1!!
        if(n < ((int)converter.get(romanInput.charAt(i+1)))){
Trinimon
  • 13,839
  • 9
  • 44
  • 60
0

The problem is when i= romanInput.length() - 1

You should check that i is less than romanInput.length() - 1

if (i < romanInput.length() - 1) {
    if(n < ((int)converter.get(romanInput.charAt(i+1)))){