Converting integers to roman numerals

前端 未结 29 2296
走了就别回头了
走了就别回头了 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:40

    The solution is lengthy, but easy to understand for a beginner. Process up to 3000

    namespace RomansTranslator
    {
        using System;
        using System.Collections.Generic;
        /// <summary>
        /// Accepts a number (between 1 and 3000) and prints its Roman equivalent.
        /// </summary>
        class Program
        {
            static void Main(string[] args)
            {
                string number = string.Empty;
                Console.Write("Enter the Numeric number : ");
                number = Console.ReadLine();
                if (IsValid(number)) // Validates the input
                {
                    string roman = ConvertToRoman(number);
                    Console.WriteLine("Roman Number is " + roman);
                }
                else
                {
                    Console.WriteLine("Invalid Number");
                }
                Console.ReadKey();
            }
    
            private static string ConvertToRoman(string numberString)
            {
                string romanValue = string.Empty;
                int number = Convert.ToInt32(numberString);
                if (number >= 1)
                {
                    // Loop through each roman character from highest 
                    foreach (int item in RomanDictionary().Keys)
                    {
                        while (number >= item)
                        {
                            romanValue = romanValue + RomanString(item);
                            number -= item;
                        }
                    }
                }
                return romanValue;
            }
    
            /// <summary>
            /// Returns Roman Equvalent
            /// </summary>
            /// <param name="n"></param>
            /// <returns></returns>
            private static string RomanString(int n)
            {
                string romanString = string.Empty;
                romanString = RomanDictionary()[n].ToString();
                return romanString;
            }
    
            /// <summary>
            /// List of Roman Characters 
            /// </summary>
            /// <returns></returns>
            private static Dictionary<int, string> RomanDictionary()
            {
    
                Dictionary<int, string> romanDic = new Dictionary<int, string>();
                romanDic.Add(1000, "M");
                romanDic.Add(900, "CM");
                romanDic.Add(500, "D");
                romanDic.Add(400, "CD");
                romanDic.Add(100, "C");
                romanDic.Add(90, "XC");
                romanDic.Add(50, "L");
                romanDic.Add(40, "XL");
                romanDic.Add(10, "X");
                romanDic.Add(9, "IX");
                romanDic.Add(5, "V");
                romanDic.Add(4, "IV");
                romanDic.Add(1, "I");
                return romanDic;
            }
    
    
            /// <summary>
            /// Validates the Input
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            private static bool IsValid(string input)
            {
                int value = 0;
                bool isValid = false;
                if (int.TryParse(input, out value))
                {
                    if (value <= 3000)
                    {
                        isValid = true;
                    }
                }
                return isValid;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-02 09:42

    Here is a slim solution from DotNetSnippets

    private string ToRomanNumber(int number)
    {
        StringBuilder result = new StringBuilder();
        int[] digitsValues = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
        string[] romanDigits = { "I", "IV", "V", "IX", "X", "XL", "L", "XC", "C", "CD", "D", "CM", "M" };
        while (number > 0)
        {
            for (int i = digitsValues.Count() - 1; i >= 0; i--)
                if (number / digitsValues[i] >= 1)
                {
                    number -= digitsValues[i];
                    result.Append(romanDigits[i]);
                    break;
                }
        }
        return result.ToString();
    }
    
    0 讨论(0)
  • 2020-12-02 09:44

    I can provide a method which is comparatively simpler than the existing

    using Microsoft.VisualBasic;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Data;
    using System.Diagnostics;
    public class Form1
    {
        int[] indx = {
            1,
            2,
            3,
            4,
            5,
            10,
            50,
            100,
            500,
            1000
            // initialize array of integers 
        };
        string[] row = {
            "I",
            "II",
            "III",
            "IV",
            "V",
            "X",
            "L",
            "C",
            "D",
            "M"
            //Carasponding roman letters in for the numbers in the array
        };
            // integer to indicate the position index for link two arrays 
        int limit = 9;
            //string to store output
        string output = "";
        private void Button1_Click(System.Object sender, System.EventArgs e)
        {
            int num = 0;
            // stores the input 
            output = "";
            // clear output before processing
            num = Convert.ToInt32(txt1.Text);
            // get integer value from the textbox
            //Loop until the value became 0
            while (num > 0) {
                num = find(num);
                //call function for processing
            }
            txt2.Text = output;
            // display the output in text2
        }
        public int find(int Num)
        {
            int i = 0;
            // loop variable initialized with 0
            //Loop until the indx(i).value greater than or equal to num
            while (indx(i) <= Num) {
                i += 1;
            }
            // detemine the value of limit depends on the itetration
            if (i != 0) {
                limit = i - 1;
            } else {
                limit = 0;
            }
            output = output + row(limit);
            //row(limit) is appended with the output
            Num = Num - indx(limit);
            // calculate next num value
            return Num;
            //return num value for next itetration 
        }
    }
    
    0 讨论(0)
  • 2020-12-02 09:46

    @Backwards_Dave You wanted a solution that goes to max number, here you go:

    public class ConvertDecimalNumberToRomanNumberType
    {
        public class RomanNumberType
        {
            public string RomanNumber;
            public int RomanNumberValue;
        }
    
        public List<RomanNumberType> RomanNumbers;
    
        public void Initialize()
        {
            RomanNumbers = new List<RomanNumberType>();
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "M", RomanNumberValue = 1000 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "CM", RomanNumberValue = 900 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "D", RomanNumberValue = 500 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "CD", RomanNumberValue = 400 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "C", RomanNumberValue = 100 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "XC", RomanNumberValue = 90 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "L", RomanNumberValue = 50 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "XL", RomanNumberValue = 40 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "X", RomanNumberValue = 10 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "IX", RomanNumberValue = 9 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "V", RomanNumberValue = 5 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "IV", RomanNumberValue = 4 });
    
            RomanNumbers.Add(new RomanNumberType() { RomanNumber = "I", RomanNumberValue = 1 });
        }
    
        public string ConvertDecimalNumberToRomanNumber(int GetConvertDecimalNumberToRomanNumber)
        {
            string
                FunctionResult
                , CurrentRomanNumber = "";
    
            int
                FunctionGet = GetConvertDecimalNumberToRomanNumber
                , DecimalNumberRemaining = FunctionGet;
    
            foreach(RomanNumberType RomanNumber in RomanNumbers)
                while(RomanNumber.RomanNumberValue <= DecimalNumberRemaining)
                {
                    DecimalNumberRemaining -= RomanNumber.RomanNumberValue;
    
                    CurrentRomanNumber += RomanNumber.RomanNumber;
                }
    
            FunctionResult = CurrentRomanNumber;
    
            return FunctionResult;
        }
    }
    

    usage :

    ConvertDecimalNumberToRomanNumberType ConvertDecimalNumberToRomanNumberObject = new ConvertDecimalNumberToRomanNumberType();
    
    ConvertDecimalNumberToRomanNumberObject.Initialize();
    
    var SomeVariable = ConvertDecimalNumberToRomanNumberObject.ConvertDecimalNumberToRomanNumber(1999);
    
    0 讨论(0)
  • 2020-12-02 09:49

    Here's a much simpler algorithm - forgive me, I don't know C# so I'm writing this in JavaScript, but the same algorithm should apply (and I've commented so you can understand the algorithm):

    function intToRoman(int) {
    
        // create 2-dimensional array, each inner array containing 
        // roman numeral representations of 1-9 in each respective 
        // place (ones, tens, hundreds, etc...currently this handles
        // integers from 1-3999, but could be easily extended)
        var romanNumerals = [
            ['', 'i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix'], // ones
            ['', 'x', 'xx', 'xxx', 'xl', 'l', 'lx', 'lxx', 'lxxx', 'xc'], // tens
            ['', 'c', 'cc', 'ccc', 'cd', 'd', 'dc', 'dcc', 'dccc', 'cm'], // hundreds
            ['', 'm', 'mm', 'mmm'] // thousands
        ];
    
        // split integer string into array and reverse array
        var intArr = int.toString().split('').reverse(),
            len = intArr.length,
            romanNumeral = '',
            i = len;
    
        // starting with the highest place (for 3046, it would be the thousands 
        // place, or 3), get the roman numeral representation for that place 
        // and append it to the final roman numeral string
        while (i--) {
            romanNumeral += romanNumerals[ i ][ intArr[i] ];
        }
    
        return romanNumeral;
    
    }
    
    console.log( intToRoman(3046) ); // outputs mmmxlvi
    
    0 讨论(0)
  • 2020-12-02 09:49

    This should be the simplest solution.

    public string IntToRoman(int num)
    {
        var result = string.Empty;
        var map = new Dictionary<string, int>
        {
            {"M", 1000 },
            {"CM", 900},
            {"D", 500},
            {"CD", 400},
            {"C", 100},
            {"XC", 90},
            {"L", 50},
            {"XL", 40},
            {"X", 10},
            {"IX", 9},
            {"V", 5},
            {"IV", 4},
            {"I", 1}
        };
        foreach (var pair in map)
        {
            result += string.Join(string.Empty, Enumerable.Repeat(pair.Key, num / pair.Value));
            num %= pair.Value;
        }
        return result;
    }
    
    0 讨论(0)
提交回复
热议问题