Я создал этот класс, который делает decimal <=> roman
public static class Roman
{
public static readonly Dictionary<char, int> RomanNumberDictionary;
public static readonly Dictionary<int, string> NumberRomanDictionary;
static Roman()
{
RomanNumberDictionary = new Dictionary<char, int>
{
{ 'I', 1 },
{ 'V', 5 },
{ 'X', 10 },
{ 'L', 50 },
{ 'C', 100 },
{ 'D', 500 },
{ 'M', 1000 },
};
NumberRomanDictionary = new Dictionary<int, string>
{
{ 1000, "M" },
{ 900, "CM" },
{ 500, "D" },
{ 400, "CD" },
{ 100, "C" },
{ 90, "XC" },
{ 50, "L" },
{ 40, "XL" },
{ 10, "X" },
{ 9, "IX" },
{ 5, "V" },
{ 4, "IV" },
{ 1, "I" },
};
}
public static string To(int number)
{
var roman = new StringBuilder();
foreach (var item in NumberRomanDictionary)
{
while (number >= item.Key)
{
roman.Append(item.Value);
number -= item.Key;
}
}
return roman.ToString();
}
public static int From(string roman)
{
int total = 0;
int current, previous = 0;
char currentRoman, previousRoman = '\0';
for (int i = 0; i < roman.Length; i++)
{
currentRoman = roman[i];
previous = previousRoman != '\0' ? RomanNumberDictionary[previousRoman] : '\0';
current = RomanNumberDictionary[currentRoman];
if (previous != 0 && current > previous)
{
total = total - (2 * previous) + current;
}
else
{
total += current;
}
previousRoman = currentRoman;
}
return total;
}
}
Некоторые юнит-тесты для To
метода:
[TestClass]
public class DecimalToRomanTest
{
[TestMethod]
public void Roman_1_I()
{
Assert.AreEqual("I", Roman.To(1));
}
[TestMethod]
public void Roman_2_II()
{
Assert.AreEqual("II", Roman.To(2));
}
[TestMethod]
public void Roman_3_III()
{
Assert.AreEqual("III", Roman.To(3));
}
[TestMethod]
public void Roman_4_IV()
{
Assert.AreEqual("IV", Roman.To(4));
}
[TestMethod]
public void Roman_5_V()
{
Assert.AreEqual("V", Roman.To(5));
}
[TestMethod]
public void Roman_9_IX()
{
Assert.AreEqual("IX", Roman.To(9));
}
[TestMethod]
public void Roman_10_X()
{
Assert.AreEqual("X", Roman.To(10));
}
[TestMethod]
public void Roman_49_XLIX()
{
Assert.AreEqual("XLIX", Roman.To(49));
}
[TestMethod]
public void Roman_50_L()
{
Assert.AreEqual("L", Roman.To(50));
}
[TestMethod]
public void Roman_100_C()
{
Assert.AreEqual("C", Roman.To(100));
}
[TestMethod]
public void Roman_400_CD()
{
Assert.AreEqual("CD", Roman.To(400));
}
[TestMethod]
public void Roman_500_D()
{
Assert.AreEqual("D", Roman.To(500));
}
[TestMethod]
public void Roman_900_CM()
{
Assert.AreEqual("CM", Roman.To(900));
}
[TestMethod]
public void Roman_1000_M()
{
Assert.AreEqual("M", Roman.To(1000));
}
[TestMethod]
public void Roman_11984_MMMMMMMMMMMCMLXXXIV()
{
Assert.AreEqual("MMMMMMMMMMMCMLXXXIV", Roman.To(11984));
}
}
Некоторые юнит-тесты для From
метода:
[TestClass]
public class RomanToDecimalTest
{
[TestMethod]
public void Roman_I_1()
{
Assert.AreEqual(1, Roman.From("I"));
}
[TestMethod]
public void Roman_II_2()
{
Assert.AreEqual(2, Roman.From("II"));
}
[TestMethod]
public void Roman_III_3()
{
Assert.AreEqual(3, Roman.From("III"));
}
[TestMethod]
public void Roman_IV_4()
{
Assert.AreEqual(4, Roman.From("IV"));
}
[TestMethod]
public void Roman_V_5()
{
Assert.AreEqual(5, Roman.From("V"));
}
[TestMethod]
public void Roman_IX_9()
{
Assert.AreEqual(9, Roman.From("IX"));
}
[TestMethod]
public void Roman_X_10()
{
Assert.AreEqual(10, Roman.From("X"));
}
[TestMethod]
public void Roman_XLIX_49()
{
Assert.AreEqual(49, Roman.From("XLIX"));
}
[TestMethod]
public void Roman_L_50()
{
Assert.AreEqual(50, Roman.From("L"));
}
[TestMethod]
public void Roman_C_100()
{
Assert.AreEqual(100, Roman.From("C"));
}
[TestMethod]
public void Roman_CD_400()
{
Assert.AreEqual(400, Roman.From("CD"));
}
[TestMethod]
public void Roman_D_500()
{
Assert.AreEqual(500, Roman.From("D"));
}
[TestMethod]
public void Roman_CM_900()
{
Assert.AreEqual(900, Roman.From("CM"));
}
[TestMethod]
public void Roman_M_1000()
{
Assert.AreEqual(1000, Roman.From("M"));
}
[TestMethod]
public void Roman_MMMMMMMMMMMCMLXXXIV_11984()
{
Assert.AreEqual(11984, Roman.From("MMMMMMMMMMMCMLXXXIV"));
}
}