Feedback

C# - Römische Zahlen / Roman Numerals

Veröffentlicht von am 10/8/2012
(1 Bewertungen)
Dieser Code überprüft die Eingabe auf syntaktische Korrektheit der römischen Zahl und konvertiert sie dann in eine Dezimalzahl

---
This code checks the input for formal correctnes of the roman number and the converts it into a decimal number
using System;
using System.Collections.Generic;

namespace RomanNumerals
{
    public static class Program
    {
        public static void Main()
        {
            try
            {
                Dictionary<Char, UInt16> romanNumerals;
                String input;
                List<UInt16> numbers;
                UInt16 highestNumber;
                String highestNumeral;
                UInt16 result;
                UInt16 dCount;
                UInt16 cCount;
                UInt16 lCount;
                UInt16 xCount;
                UInt16 vCount;
                UInt16 iCount;

                romanNumerals = new Dictionary<Char, UInt16>(7);
                romanNumerals.Add('I', 1);
                romanNumerals.Add('V', 5);
                romanNumerals.Add('X', 10);
                romanNumerals.Add('L', 50);
                romanNumerals.Add('C', 100);
                romanNumerals.Add('D', 500);
                romanNumerals.Add('M', 1000);
                Console.WriteLine("Please enter a roman numeral and press <Enter>");
                input = Console.ReadLine().ToUpper();
                numbers = new List<UInt16>(input.Length);
                #region Input Checking

                //The following code check against the following rules:

                //The numbers have to be steady or descending
                //You can substract C only from M and D
                //You can substract X only from C and L
                //You can substract I only from X and V
                //D, L and V can only appear once
                //C, X and I can only appear thrice in a row

                highestNumber = 1000;
                highestNumeral = "M";
                dCount = 0;
                cCount = 0;
                lCount = 0;
                xCount = 0;
                vCount = 0;
                iCount = 0;
                foreach(Char letter in input)
                {
                    UInt16 number;

                    if(romanNumerals.TryGetValue(letter, out number) == false)
                    {
                        Console.WriteLine("'{0}' is not a roman number", letter);
                        return;
                    }
                    numbers.Add(number);
                }
                for(Int32 i = 0; i < numbers.Count; i++)
                {
                    if(i < numbers.Count - 1)
                    {
                        if(numbers[i] < numbers[i + 1])
                        {
                            UInt16 substraction;

                            if(numbers[i] == 1)
                            {
                                if((numbers[i + 1] != 5) && (numbers[i + 1] != 10))
                                {
                                    Console.WriteLine("You can substract 'I' only from 'V' or 'X'");
                                    return;
                                }
                            }
                            else if(numbers[i] == 10)
                            {
                                if((numbers[i + 1] != 50) && (numbers[i + 1] != 100))
                                {
                                    Console.WriteLine("You can substract 'X' only from 'L' or 'C'");
                                    return;
                                }
                            }
                            else if(numbers[i] == 100)
                            {
                                if((numbers[i + 1] != 500) && (numbers[i + 1] != 1000))
                                {
                                    Console.WriteLine("You can substract 'C' only from 'D' or 'M'");
                                    return;
                                }
                            }
                            else
                            {
                                Console.WriteLine("You cannot substract '{0}' from '{1}'", input[i], input[i + 1]);
                                return;
                            }
                            substraction = (UInt16)(numbers[i + 1] - numbers[i]);
                            if(substraction > highestNumber)
                            {
                                Console.WriteLine("You cannot have '{0}' following '{1}'", input[i].ToString() + input[i + 1].ToString(), highestNumeral);
                                return;
                            }
                            else
                            {
                                highestNumeral = input[i].ToString() + input[i + 1].ToString();
                                if(substraction == highestNumber)
                                {
                                    Console.WriteLine("You cannot have '{0}' following '{0}'", highestNumeral);
                                    return;
                                }
                                highestNumber = (UInt16)(numbers[i] - 1);
                                i++;
                                if(DetermineMaxSequentials(input, numbers, i, ref dCount, ref cCount, ref lCount, ref xCount, ref vCount, ref iCount, true))
                                {
                                    return;
                                }
                                continue;
                            }
                        }
                    }
                    if(numbers[i] > highestNumber)
                    {
                        Console.WriteLine("You cannot have '{0}' following '{1}'", input[i], highestNumeral);
                        return;
                    }
                    else
                    {
                        if(DetermineMaxSequentials(input, numbers, i, ref dCount, ref cCount, ref lCount, ref xCount, ref vCount, ref iCount, false))
                        {
                            return;
                        }
                        highestNumber = numbers[i];
                        highestNumeral = input[i].ToString();
                    }
                }
                #endregion
                #region Calculation
                result = 0;
                for(Int32 i = 0; i < numbers.Count; i++)
                {
                    if(i == numbers.Count - 1)
                    {
                        result += numbers[i];
                    }
                    else
                    {
                        if(numbers[i] < numbers[i + 1])
                        {
                            UInt16 substraction;

                            substraction = (UInt16)(numbers[i + 1] - numbers[i]);
                            result += substraction;
                            i++;
                        }
                        else
                        {
                            result += numbers[i];
                        }
                    }
                }
                #endregion
                Console.WriteLine("Result: {0}", result);
            }
            catch(Exception ex)
            {
                Console.WriteLine("Exception: {0}", ex.Message);
            }
            finally
            {
                Console.WriteLine("Press <Enter> to exit");
                Console.ReadLine();
            }
        }

        #region Input Checking
        private static Boolean DetermineMaxSequentials(String input
            , List<UInt16> numbers
            , Int32 index
            , ref UInt16 dCount
            , ref UInt16 cCount
            , ref UInt16 lCount
            , ref UInt16 xCount
            , ref UInt16 vCount
            , ref UInt16 iCount
            , Boolean isSubstraction)
        {
            Boolean abort;
            UInt16 maxOne;
            UInt16 maxThree;

            maxOne = 1;
            if(isSubstraction)
            {
                maxThree = 4;
            }
            else
            {
                maxThree = 3;
            }
            if(DetermineMaxSequentials(input, numbers, index, ref dCount, maxOne, 500, "one", out abort) == false)
            {
                if(DetermineMaxSequentials(input, numbers, index, ref cCount, maxThree, 100, "three", out abort) == false)
                {
                    if(DetermineMaxSequentials(input, numbers, index, ref lCount, maxOne, 50, "one", out abort) == false)
                    {
                        if(DetermineMaxSequentials(input, numbers, index, ref xCount, maxThree, 10, "three", out abort) == false)
                        {
                            if(DetermineMaxSequentials(input, numbers, index, ref vCount, maxOne, 5, "one", out abort) == false)
                            {
                                DetermineMaxSequentials(input, numbers, index, ref iCount, maxThree, 1, "three", out abort);
                            }
                        }
                    }
                }
            }
            return (abort);
        }

        private static Boolean DetermineMaxSequentials(String input
            , List<UInt16> numbers
            , Int32 index
            , ref UInt16 count
            , UInt16 maxCount
            , UInt16 value
            , String numberWord
            , out Boolean abort)
        {
            abort = false;
            if(numbers[index] == value)
            {
                count++;
                if(count > maxCount)
                {
                    Console.WriteLine("You cannot have more than {0} '{1}'", numberWord, input[index]);
                    abort = true;
                }
                return (true);
            }
            return (false);
        }
        #endregion
    }
}

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!