2016-07-27 2 views
-1

Следующий класс содержит метод fromRomanToArabic() в этом методе. Я пытаюсь преобразовать арабский номер в римский номер. метод должен действовать следующим образом:Указатель строки из связанной ошибки

  • взять пользователя строку из объекта
  • itterate через строку
  • просуммировать значения, связанные с персонажами. Если число, связанное с символами, больше предыдущего, вычитайте значение символа из суммы.

вот мой код:

package romantoarabicnums; 

import javax.swing.JOptionPane; 


public class RomanToArabicNums { 
    private static String userString; 
    private static int userNumber; 
    private static char letter; 
    private static int letterNum; 

    public RomanToArabicNums (String s) throws NumberFormatException { 
     for (int i = 0; i < s.length(); i++) { 

      if (s.charAt(i) == 'M' ||s.charAt(i) == 'D' ||s.charAt(i) == 'C' ||s.charAt(i) == 'X' || 
       s.charAt(i) == 'V' ||s.charAt(i) == 'I' ||s.charAt(i) == 'L') { 
       userString += s.charAt(i); 
      } 
      else {throw new NumberFormatException("Only M,C,D,X,V and I allowed");} 
     } 
    } 
    public RomanToArabicNums (int num) throws NullPointerException { 
     if (num >= 1 && num <= 3999) { 
      RomanToArabicNums.userNumber = num; 
     } 
     else {throw new NumberFormatException("numbers between 1 and 3999 only!");} 
    } 
    public RomanToArabicNums (char let, int num) { 
     RomanToArabicNums.letter = let; 
     RomanToArabicNums.letterNum = num; 
    } 
    public static void main(String[] args) { 
     RomanToArabicNums r2 = new RomanToArabicNums("MCMXCV"); 
     System.out.println("the arabic number is: " + r2.fromRomanToArabic()); 

    } 
    /* convert Roman characters to Arabic numbers */ 
    public int fromRomanToArabic() { 
      int sum = 0; 

      for (int i = 0; i <= userString.length(); i++) { 
       /**/ 
       if (userString.charAt(i) == 'M') { 
        sum += 1000; 
       } 
       /**/ 
       if (userString.charAt(i) == 'D') { 
        if (userString.charAt(i + 1) == 'M') { 
         sum -= 500; 
        } else { 
         sum += 500; 
        } 
       } 
       /**/ 
       if (userString.charAt(i) == 'C') { 
        if (userString.charAt(i + 1) == 'M' || userString.charAt(i + 1) == 'D') { 
         sum -= 100; 
        } else { 
         sum += 100; 
        } 
       } 
       /**/ 
       if (userString.charAt(i) == 'L') { 
        if (userString.charAt(i + 1) == 'M' || userString.charAt(i + 1) == 'D' 
          || userString.charAt(i + 1) == 'C') { 
         sum -= 50; 
        } else { 
         sum += 50; 
        } 
       } 
       /**/ 
       if (userString.charAt(i) == 'X') { 
        if (userString.charAt(i + 1) == 'M' || userString.charAt(i + 1) == 'D' 
          || userString.charAt(i + 1) == 'C' || userString.charAt(i + 1) == 'L') { 
         sum -= 10; 
        } else { 
         sum += 10; 
        } 
       } 
       /**/ 
       if (userString.charAt(i) == 'V') { 
        if (userString.charAt(i + 1) == 'M' || userString.charAt(i + 1) == 'D' 
          || userString.charAt(i + 1) == 'C' || userString.charAt(i + 1) == 'L' 
          || userString.charAt(i + 1) == 'X') { 
         sum -= 5; 
        } else { 
         sum += 5; 
        } 
       } 
       /**/ 
       if (userString.charAt(i) == 'I') { 
        if (userString.charAt(i + 1) == 'M' || userString.charAt(i + 1) == 'D' 
          || userString.charAt(i + 1) == 'C' || userString.charAt(i + 1) == 'L' 
          || userString.charAt(i + 1) == 'X' || userString.charAt(i + 1) == 'V') { 
         sum -= 1; 
        } else { 
         sum += 1; 
        } 
       } 
      } 
      return sum; 

    } 
} 

и вот ошибка: enter image description here

Примечание: Я думаю, что ошибка происходит из-за количества строк элементов является менее, что шаги в петля для петли

+1

Возможный дубликат [string index out of bound exception, String index out the range] (http://stackoverflow.com/questions/28777630/string-index-out-of-bound-exception-string-index-out -of-range) – xenteros

+0

В чем причина добавления функциональности преобразования арабского языка в римский класс под названием RomanToArabicNums? – xenteros

ответ

1

В дополнение к Jens' и ответы Энди вы должны действительно проверить i + 1 < userString.length(), так как вы используете userString.charAt(i + 1) == 'M'.

Это также вызовет IndexOutOfBoundsException, если вы указали указатель последнего символа.

Обратите внимание, что вам необходимо обработать последний символ соответственно или сохранить i < userString.length() и добавить чек, если i + 1 превышает длину строки, где бы вы ни использовали userString.charAt(i + 1).

+0

за ответ! это почти решило проблему. Я получаю возвращаемое значение int 1990. Для MCMXCV он должен вернуться 1995 – zamzam

+0

@zamzam Как я уже сказал, вам нужно применить свою логику к последнему персонажу отдельно после цикла, так как вы выходите из него слишком рано. – eol

2

Итак, строки Zero основаны, вам необходимо запустить Loop до: i < userString.length()

for (int i = 0; i < userString.length(); i++) { 

И еще есть множество ошибок. Вы получаете символ из длины вашей строки.

+0

спасибо, такая же ошибка – zamzam

+0

@zamzam Нет не такая же ошибка. Но у вас много ошибок с индексом в строках. – Jens

+0

@Downvoter: пожалуйста, объясните – Jens

0

Ссылаясь на Javadoc из String.charAt(int):

[throws] IndexOutOfBoundsException - if the index argument is negative or not less than the length of this string.

Так в любом месте вы звоните userString.charAt, вам необходимо убедиться, что индекс соответствует этим условиям:

  • i <= userString.length() должен быть i < userString.length(). Это означает, что все звонки userString.charAt(i) преуспевают;
  • Все звонки в userString.charAt(i + 1) требуют предварительной проверки, что i + 1 < userString.length(), например.

    if (i + 1 < userString.length() && userString.charAt(i + 1) == 'M') { 
    

    Логически эти вызовы проверяют «следующий символ». Проверив значение i + 1 первых, эта проверка в основном говорят:

    if ((there is a next character) AND (the next character is 'M')) { 
    
+0

Это не единственная проблема с кодом. Он также называет userString.charAt (i + 1) в разных местах своего кода, поэтому, даже если он исправляет значение for, он все равно выдаст это исключение. – Mark

+0

@Mark вы правы, такая же ошибка повторится – zamzam

+0

@zamzam это * не * та же ошибка, только тот же * вид * ошибки. Если вы внимательно посмотрите на трассировку стека до и после изменения защиты цикла, вы увидите, что исключение выбрано в разных строках. –

0

я не получил это вообще. Но сделать следующее в вашем методе:

for (int i = 0; i <= userString.length(); i++) 

Вы должны сделать это:

for (int i = 0; i < userString.length(); i++) 
+0

спасибо, ту же ошибку – zamzam

0

Вы используете userString.charAt(i + 1) в цикле, где i <= userString.length()

так есть 2 индексов, которые собираются из-за границы i == n - 1 и i == n.

изменить определение цикла из

for (int i = 0; i <= userString.length(); i++) { 

в

for (int i = 0; i < userString.length() - 1; i++) { 
+0

благодарю вас за ответ! это почти решило проблему. Я получаю обратную стоимость int. 1990. Для MCMXCV он должен вернуть 1995 – zamzam

0

В коде есть две проблемы. Одно очевидно - вы зацикливаете for (int i = 0; i <= userString.length(); i++) вместо for (int i = 0; i < userString.length(); i++). Второй - более скрытый. Вы не проверяете, есть ли i + 1 < userString.length(), прежде чем звонить charAt(i+1). Исправление этих двух ошибок позволит вам преобразовать действительные римские цифры.

Еще одна вещь. Класс RomanToArabic - не лучшее место для конвертации Arabic в Roman. Рассмотрим рефакторинг имени вашего класса на RomanArabicConverter или разделите свою логику на два отдельных класса и укажите один класс, который будет aggregate оба из них.

Смежные вопросы