Как преобразовать римские цифры в арабские на Java?

Как преобразовать римские цифры в арабские на Java чтобы в дальнейшем выполнять с ними простейшие арифметические действия?


Ответы (2 шт):

Автор решения: Andrew

Вот например есть вариант:

public enum Roman {
    I(1), V(5), X(10), L(50), C(100), D(500), M(1000);
    private final int value;
    private Roman(int value) {
        this.value = value;
    }
    public int toInt() {
        return value;
    }
}

и дальше конвертация выглядит так:

Roman.valueOf("X").toInt();

если же у вас больше 10, то необходимо это обработать:

public enum Roman {
    public boolean shouldCombine(Roman next) {
        return this.value < next.value;
    }
    public int toInt(Roman next) {
        return next.value - this.value;
    }
}

и получить результат:

List<Roman> romans = new ArrayList<>();
input.chars().mapToObj(Character::valueOf)
    .map(Roman::valueOf).forEach(romans::add);
int value = 0;
while (!romans.isEmpty()) {
    Roman current = romans.remove(0);
    if (!romans.isEmpty() && current.shouldCombine(romans.get(0))
        value += current.toInt(romans.remove(0));
    else
        value += current.ToInt();
}

вот есть подобные вопросы: 1, 2 и первоисточник

→ Ссылка
Автор решения: Barmaley

Делюсь из своих закромов - уже не помню для чего писал (наверное был какой-то тест, видимо условие было не использовать коллекции типа Map, оттуда и возник дихотомический поиск):

public class Roman2Arabic {
    private static int[] intervals={0, 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
    private static String[] numerals={"", "I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M"};
    
    public static void main(String args[]) {
        int i=1974;
        String roman=toRoman(i);
        int arabic = toArabic(roman);
        System.out.println("Initial="+i+", roman="+roman+", arabic="+arabic);
    }
    
     /**
     * Dichotomic search in sorted array of intervals
     * @param number
     * @return floor index closest to number
     */
    private final static int findFloor(final int number, final int firstIndex, final int lastIndex) {
        if(firstIndex==lastIndex)
            return firstIndex;
        if(intervals[firstIndex]==number)
            return firstIndex;
        if(intervals[lastIndex]==number)
            return lastIndex;
        final int median=(lastIndex+firstIndex)/2;
        if(median==firstIndex)
            return firstIndex;
        if(number == intervals[median])
            return median;
        if(number > intervals[median])
            return findFloor(number, median, lastIndex);
        else
            return findFloor(number, firstIndex, median);

    }

    public final static String toRoman(final int number) {
        int floorIndex=findFloor(number, 0, intervals.length-1);
        if(number==intervals[floorIndex])
            return numerals[floorIndex];
        return numerals[floorIndex]+toRoman(number-intervals[floorIndex]);
    }
    
    public static int toArabic(String roman) {
        int result = 0;
        for (int i = intervals.length-1; i >= 0; i-- ) {
            while (roman.indexOf(numerals[i]) == 0 && numerals[i].length() > 0) {
                result += intervals[i];
                roman = roman.substring(numerals[i].length());
            }
        }
        return result;
    }
}
→ Ссылка