из римских в десятичные

225
30 декабря 2017, 03:47

Делаю конвертер из римских цифр в десятичные и вот который час танцую с бубном перед ошибкой, но как то никак...

public static int roman2Decimal(String roman){
    int integerValue = 0;
    for (int i = 0; i < roman.length(); i++) {
        char ch = roman.charAt(i);
        int number = letterToNumber(ch);
        if (number == -1){
            throw new NumberFormatException("Invalid format");
        }
        integerValue += number;
    }
    return integerValue;
}

Беда заключается в том что когда передаю методу, к примеру, XXIV то получаю 26 вместо 24. Понимаю что весь трабл в integerValue += number; в этом месте, но вот как победить, что бы не ломать все что уже написал не могу понять.

З.Ы. Метод letterToNumber:

private static int letterToNumber(char letter){
        switch (letter) {
            case 'I':  return 1;
            case 'V':  return 5;
            case 'X':  return 10;
            case 'L':  return 50;
            case 'C':  return 100;
            case 'D':  return 500;
            case 'M':  return 1000;
            default:   return -1;
        }
    }
Answer 1
public class RomanToDecimal {
public static void romanToDecimal(java.lang.String romanNumber) {
    int decimal = 0;
    int lastNumber = 0;
    String romanNumeral = romanNumber.toUpperCase();
    /* operation to be performed on upper cases even if user 
       enters roman values in lower case chars */
    for (int x = romanNumeral.length() - 1; x >= 0 ; x--) {
        char convertToDecimal = romanNumeral.charAt(x);
        switch (convertToDecimal) {
            case 'M':
                decimal = processDecimal(1000, lastNumber, decimal);
                lastNumber = 1000;
                break;
            case 'D':
                decimal = processDecimal(500, lastNumber, decimal);
                lastNumber = 500;
                break;
            case 'C':
                decimal = processDecimal(100, lastNumber, decimal);
                lastNumber = 100;
                break;
            case 'L':
                decimal = processDecimal(50, lastNumber, decimal);
                lastNumber = 50;
                break;
            case 'X':
                decimal = processDecimal(10, lastNumber, decimal);
                lastNumber = 10;
                break;
            case 'V':
                decimal = processDecimal(5, lastNumber, decimal);
                lastNumber = 5;
                break;
            case 'I':
                decimal = processDecimal(1, lastNumber, decimal);
                lastNumber = 1;
                break;
        }
    }
    System.out.println(decimal);
}
public static int processDecimal(int decimal, int lastNumber, int lastDecimal) {
    if (lastNumber > decimal) {
        return lastDecimal - decimal;
    } else {
        return lastDecimal + decimal;
    }
}
public static void main(java.lang.String args[]) {
    romanToDecimal("XIV");
}

}

Answer 2

вам нужно проверить, что следующее число меньше, чем текущее. Римские числа по убыванию строятся.

public static int roman2Decimal(String roman){
    int integerValue = 0;
    for (int i = 0; i < roman.length(); i++) {
        char ch = roman.charAt(i);
        int number = letterToNumber(ch);
        if (number == -1) {
            throw new NumberFormatException("Invalid format");
        }
        if (i +1 < roman.length()) {
            int nextNumber = letterToNumber(roman.charAt(i+1));
            if (nextNumber > number) {
                integerValue += (nextNumber - number);
                i++;
            }
            else {
                integerValue += number;
            }
        }
    }
    return integerValue;
}
Answer 3

Если нигде не ошибся

private static int letterToNumber(char letter){
    switch (letter) {
        case 'I': return 1;
        case 'V': return 5;
        case 'X': return 10;
        case 'L': return 50;
        case 'C': return 100;
        case 'D': return 500;
        case 'M': return 1000;
        default: throw new NumberFormatException("Invalid format");
    }
}
public static int roman2Decimal(String roman){
    if (roman.length() == 0)
      return 0;
    int integerValue = 0;
    int prevNumber = letterToNumber(roman.charAt(0));
    for (int i = 1; i < roman.length(); i++) {
        char ch = roman.charAt(i);
        int number = letterToNumber(ch);
        if (number <= prevNumber)
          integerValue += prevNumber;
        else
          integerValue -= prevNumber;
        prevNumber = number;
    }
    integerValue += prevNumber;
    return integerValue;
}
Answer 4

Вышел победителем вот так:

public static int roman2Decimal(String roman){
    int integerValue = 0;
    for (int i = 0; i < roman.length(); i++) {
        char ch = roman.charAt(i);
        int number = letterToNumber(ch);
        if (number == -1){
            throw new NumberFormatException("Invalid format");
        }
        integerValue += number;
    }
    if(roman.contains("IV")||roman.contains("IX"))
        integerValue -=2;
    return integerValue;
}
READ ALSO
Android.Java.Sqlite.Не находит столбец в таблице

Android.Java.Sqlite.Не находит столбец в таблице

Не находит столбец в таблице и выдаёт такую ошибку :

250
Карта интенсивностей (heatmap) в Java

Карта интенсивностей (heatmap) в Java

Есть двумерный массив с double значениямиНа основании этого массива нужно построить карту интенсивностей (heatmap)

170
Одна Cookie на два разных сайта

Одна Cookie на два разных сайта

Есть проектУ этого проекта есть Админ панель и есть скрипт

230
Дизайн Андроид Чата

Дизайн Андроид Чата

Всем приветСделал приложения с чатом

196