C# :: Aufgabe #315

1 Lösung Lösung öffentlich

Zahlen in Wörtern ausdrücken

Anfänger - C# von Gisbert5020 - 30.04.2020 um 15:17 Uhr
Schreiben Sie ein Programm, das Zahlen von 0 bis 99 in Wörtern fasst.
Zusatzaufgabe : Erweitern Sie das Programm von 0 bis 1000.

Lösungen:

vote_ok
von daniel59 (4260 Punkte) - 06.05.2020 um 11:32 Uhr
Program.cs
Quellcode ausblenden C#-Code
using System;

namespace ConsoleGermanNumberConverter
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int i = 0; i <= 1000; i++)
            {
                string num = GermanNumberConverter.Translate(i);
                Console.WriteLine($"{i, 4} - {num}"); 
            }
            Console.ReadLine();
        }
    }
}


GermanNumberConverter.cs
Quellcode ausblenden C#-Code
using System.Collections.Generic;
using System.Linq;

namespace ConsoleGermanNumberConverter
{
    class GermanNumberConverter
    {
        const string minus = "minus ";
        static readonly Dictionary<int, string> constants = new Dictionary<int, string>()
        {
            //{0, "null" },
            {1, "eins" },
            {2, "zwei" },
            {3, "drei" },
            {4, "vier" },
            {5, "fünf" },
            {6, "sechs" },
            {7, "sieben" },
            {8, "acht" },
            {9, "neun" },
            {10, "zehn" },
            {11, "elf" },
            {12, "zwölf" },
            {13, "dreizehn" },
            {14, "vierzehn" },
            {15, "fünfzehn" },
            {16, "sechszehn" },
            {17, "siebzehn" },
            {18, "achtzehn" },
            {19, "neunzehn" },
            {20, "zwanzig" },
            {21, "einundzwanzig" },
            {31, "einunddreizig" },
            {41, "einundvierzig" },
            {51, "einundfünfzig" },
            {61, "einundsechzig" },
            {70, "siebzig" },
            {71, "einundsiebzig" },
            {81, "einundachtzig" },
            {91, "einundneunzig" },
            {100, "einhundert" },
            {1000, "eintausend" },
            {1000000, "einemillion" },
            {1000000000, "einemilliarde" },
        };

        static readonly TranslationRule[] RuleSet =
        {
            new TranslationRule() { RangeFrom = 2, RangeTo = 999, Factor = 1000000000, Suffix = "milliarden" },
            new TranslationRule() { RangeFrom = 2, RangeTo = 999, Factor = 1000000,Suffix = "millionen" },
            new TranslationRule() { RangeFrom = 2, RangeTo = 999, Factor = 1000, Suffix = "tausend" },
            new TranslationRule() { RangeFrom = 2, RangeTo = 9, Factor = 100, Suffix = "hundert" },
            new TranslationRule() { RangeFrom = 3, RangeTo = 9, Factor = 10, Suffix = "zig" }
        };

        public static string Translate(int n)
        {
            if (n == 0)
            {
                return "null";
            }
            else if (n < 0)
            {
                return minus + TranslatePositiveNumber(-n);
            }
            else
            {
                return TranslatePositiveNumber(n);
            }
        }

        private static string TranslatePositiveNumber(int n)
        {
            List<NumberElement> elements = new List<NumberElement>();
            string s = Translate(n, ref elements);

            var ret = elements.Where(a => !string.IsNullOrWhiteSpace(a.Value)).ToArray();

            string value = "";
            for (int i = 0; i < ret.Length - 2; i++)
            {
                value += ret[i];
            }
            if (ret.Length >= 2)
            {
                NumberElement secondLast = ret[ret.Length - 2];
                NumberElement last = ret[ret.Length - 1];

                if (!secondLast.Value.StartsWith("ein") && secondLast.Value.EndsWith("zig") && last.Constant >= 1 && last.Constant <= 9)
                {
                    value += last.Value + "und" + secondLast.Value;
                }
                else
                {
                    value += secondLast.Value + last.Value;
                }
            }
            else
            {
                value = ret.FirstOrDefault();
            }

            return value;
        }

        private static string Translate(int n, ref List<NumberElement> list)
        {
            if (constants.Keys.Contains(n))
            {
                list.Add(new NumberElement() { Value = constants[n], Constant = n });
                return constants[n];
            }

            string result = "";

            int v = n;
            foreach (var rule in RuleSet)
            {
                NumberElement element;
                int sub;
                if (!rule.Assign(n, out element, out sub))
                {
                    return "";
                }
                v -= sub;
                result += element;
                list.Add(element);
                if (sub > 0)
                {
                    break;
                }
            }
            if (v > 0)
            {
                result += Translate(v, ref list);
            }

            return result;
        }

        private class TranslationRule
        {
            public int RangeFrom { get; set; }
            public int RangeTo { get; set; }
            public int Factor { get; set; }
            public string Suffix { get; set; }

            public bool Assign(int n, out NumberElement element, out int sub)
            {
                element = (NumberElement)"";
                sub = 0;
                int value = n / Factor;
                sub = value * Factor;
                if (value == 0)
                {
                    return true;
                }
                if (constants.ContainsKey(sub))
                {
                    element.Value = constants[sub];
                    element.Constant = sub;
                    return true;
                }
                else if (value < RangeFrom || value > RangeTo)
                {
                    return false;
                }

                if (!constants.ContainsKey(value))
                {
                    element.Value = TranslatePositiveNumber(value);
                    if (string.IsNullOrWhiteSpace(element))
                    {
                        return false;
                    }
                    element.Value += Suffix;
                }
                else
                {
                    element.Value = constants[value] + Suffix;
                }


                return true;
            }
        }

        private class NumberElement
        {
            public string Value { get; set; }
            public int Constant { get; set; }

            public static implicit operator string(NumberElement v)
            {
                return v.Value;
            }

            public static explicit operator NumberElement(string v)
            {
                return new NumberElement() { Value = v };
            }

            public override string ToString()
            {
                return Value;
            }
        }
    }
}