Converting integers to roman numerals

前端 未结 29 2473
走了就别回头了
走了就别回头了 2020-12-02 09:16

I\'m trying to write a function that converts numbers to roman numerals. This is my code so far; however, it only works with numbers that are less than 400. Is there a quick

29条回答
  •  死守一世寂寞
    2020-12-02 09:33

    I've created this class that does decimal <=> roman

    public static class Roman
    {
        public static readonly Dictionary RomanNumberDictionary;
        public static readonly Dictionary NumberRomanDictionary;
    
        static Roman()
        {
            RomanNumberDictionary = new Dictionary
            {
                { 'I', 1 },
                { 'V', 5 },
                { 'X', 10 },
                { 'L', 50 },
                { 'C', 100 },
                { 'D', 500 },
                { 'M', 1000 },
            };
    
            NumberRomanDictionary = new Dictionary
            {
                { 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;
        }
    }
    

    Some Unit Tests for To method:

    [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));
        }
    }
    

    Some Unit Tests for From method:

    [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"));
        }
    }
    

提交回复
热议问题