Полная таблица римских цифр. Из Басры в Рим. Преобразовываем арабские числа в римские

О преобразовании.

Римские цифры - это непозиционная система счисления, то есть всё счисление идет не от разряда цифры, как в обычной десятичной системе, а непосредственно по значению цифры. Цифр в римской системе всего 7 вот они: I , V , X , L , C , D , M . Из этих цифр и составляются все числа.

I II III IV V VI VII VIII IX X
1 2 3 4 5 6 7 8 9 10
XI XX XXX XL L LX LXX LXXX XC C
11 20 30 40 50 60 70 80 90 100
CX CC CCC CD D DC DCC DCCC CM M
110 200 300 400 500 600 700 800 900 1000
Пример : 1964 = MCMLXIV

Правила преобразования арабских цифр в римские

Если цифра, стоящая слева от данной цифры, меньше её, то она вычитается из данной цифры (принцип вычитания). Если больше, то складывается (принцип сложения). Например, XLVII = XL (40 = 50 - 10) + V (5) + II (2) = 47. Но есть одно исключение. Если мы возьмем число 99 и попытаемся перевести, то должны бы получить IC. Компактно, но, не правильно. В классической системе римских цифр число стоящее справа (то есть из которого вычитается) должно быть не больше чем то, что слева умноженное на десять. То есть то же число 99 надо переводить буквально XC (90 = 100 - 10) + IX (9 = 10 - 1) = XCIX. То есть 49 нельзя записывать как IL, только как LXIX. Есть ещё одно правило. Нельзя делать повторения четырёх цифр подряд, то есть число 40 нельзя записывать как XXXX, а только как LX. Из всех этих правил вытекает, что максимальное число, которое можно записать римскими цифрами есть MMMCMXCIX = 3999. Но не стоит отчаиваться! Этруски, которые вроде бы придумали римские цифры, были умными ребятами и сделали хитро — число, подчеркнутое палочкой сверху, означает количество тысяч. То есть 4000 нужно записывать как IV. Всё просто.

Онлайн перевод арабских цифр в римские

Арабская цифра:

Римская цифра:

Доброе время суток, Хабраюзер.

Разрабатывая в основном для платформы J2ME, я всегда старался вносить какие то изюминки в свои проекты. Так, однажды, мне понадобилось выделить пункты меню.

Стандартное решение, через тире или пронумеровав их, использовать не очень хотелось, но другие варианты тогда у меня отсутствовали. Обдумывая как бы лучше оформить эти пункты, я случайно наткнулся на свою старую школьную тетрадку по истории, в которой пункты были пронумерованы с использованием римских цифр. Бинго!

Стоит признаться, на то время моих познаний в римских цифрах хватало только для подсчета до второго-третьего десятка. Что вообще то для нумерации пунктов должно было хватить. Но как любой программист, захотелось иметь готовое решение, которое смогло бы переводить любые целые десятичные арабские числа в эквивалентные им римские.

В Википедии нашлась статья с описанием Римской СС, и вскоре я набросал алгоритм перевода из арабских чисел в римские.

Основные числа:

I - 1
V - 5
X - 10
L - 50
C - 100
D - 500
M - 1000

Ноль отсутствует вообще, поэтому будем использовать пустое значение.

Итак, сам алгоритм достаточно прост:

1. Выделяем (если есть) количество целых тысяч. Полученное значение позволить сгенерировать строку с n количеством «M» (читаем, n*1000).
Пример: 2012 после первого пункта даст «MM»

2. Получаем остаток после деления на 1000, чтобы выделить в дальнейшем следующие значения.

3. Выделяем (если возможно), целые 500. При этом учитываем что если полученное значение равно 4 (5+4=9), то следует записывать как значение 1000-100, что в римский СС равнозначно «CM».
Пример: 1887 после этого пункта даст нам «MD».
1945 соответственно «MCM».

4. Получаем остаток от деления на 500.

5. Делим на 100 чтобы выделить целые сотни и складываем к предыдущему результату. Учитываем что если получили 4, что равнозначно 400, то записываем как 500-100, то есть «CD».
Пример: 1709 даст после этого шага «MDCCC».

6. Получаем остаток от деления на 100.

7. Выделяем из него целые пол сотни. Если значение будет равно 4 (то есть 90), то записываем как 100-10, что равно «XC». Иначе прибавляем к строке «L»
Пример: 1986 после всего выдаст нам «MCML».

8. Выделяем остаток от 50.

9. Выделяем целое количество десятков и складываем к строке n раз символ «X». При этом учитываем что 40 пишется как 50-10, то есть «XL».
Пример: 1986 после всего выдаст нам «MCMLXXX».

10. Получаем остаток от деления на 10. Этот шаг отличается от других тем, что можно сразу приравнять остаток к его эквиваленту. 1=I, 7=VII и так далее.

После перебора числа этим алгоритмом мы получаем примерно такое:
2012 == MMXII
Ниже исходник на Java, реализующий алгоритм.
public class RoManiac { /* Основные числа: I - 1 V - 5 X - 10 L - 50 C - 100 D - 500 M - 1000 Ноль отсутствует вообще,поэтому будем использовать пустое значение */ // Основной метод преобразования из арабских в римские public static String convert(int in) { StringBuffer a = new StringBuffer(""); // Выделяем тысячи int m1 = in / 1000; a.append(M(m1)); // то что осталось после тысяч int m2 = in % 1000; // Выделяем пятьсот из остатка от тысячи int d1 = m2 / 500; a.append(D(d1)); // остаток после выделения полтысячи int d2 = m2 % 500; // Выделяем сотни из остатка int c1 = d2 / 100; a.append(C(c1)); // остаток из сотен int c2 = d2 % 100; // Выделяем полсотни int l1 = c2 / 50; a.append(L(l1)); // остаток int l2 = c2 % 50; // Выделяем десятки int x1 = l2 / 10; a.append(X(x1)); // остаток int x2 = l2 % 10; // Выделяем то что осталось a.append(basic(x2)); return a.toString(); } // преобразовываем целые тысячи // с значениями,кратными десяти, но не 5,всё просто private static String M(int in) { StringBuffer a = new StringBuffer(""); int i = 0; while (i < in) { a.append("M"); i++; } return a.toString(); } // преобразовываем целые сотни private static String C(int in) { if (in == 4) return "CD"; //если 400, то 500-100 else if ((in != 0) && (in < 4)) { StringBuffer a = new StringBuffer(""); int i = 0; while (i < in) { a.append("C"); i++; } return a.toString(); } else return ""; } // целые десятки private static String X(int in) { if (in == 4) return "XL"; // если 40, то 50-10 else if ((in != 0) && (in < 4)) { StringBuffer a = new StringBuffer(""); int i = 0; while (i < in) { a.append("X"); i++; } return a.toString(); } else return ""; } // преобразовываем пол тысячи private static String D(int in) { if (in = 4) return "CM"; // если 900, то 1000-100 else return "D"; } private static String L(int in) { if (in = 4) return "XC"; / / если90 то100 - 10 return "L"; } // От 1 до 9, то что осталось private static String basic(int in) { String a = { "", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" }; return a; } } P.S.: Уже в процессе написания подумал что стоить реализовать обратное преобразование.