Nadesłany przez Lesław Pawlaczyk, 24 lutego 2015 12:16
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
NumbersToText.cs:
//Zamiana liczby na slowa z polska gramatyka
//Lesław Pawlaczyk
//www.algorytm.org
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace LanguageModelFilter
{
public class NumbersToText
{
# region Constant Arrays
protected static string[] SINGLES = { "", "jeden", "dwa", "trzy", "cztery", "pięć", "sześć", "siedem", "osiem", "dziewięć" };
protected static string[] TEENS = { "", "jedenaście", "dwanaście", "trzynaście", "czternaście", "piętnaście", "szesnaście", "siedemnaście", "osiemnaście", "dziewiętnaście" };
protected static string[] TENS = { "", "dziesięć", "dwadzieścia", "trzydzieści", "czterdzieści", "pięćdziesiąt", "sześćdziesiąt", "siedemdziesiąt", "osiemdziesiąt", "dziewięćdziesiąt" };
protected static string[] HUNDREDS = { "", "sto", "dwieście", "trzysta", "czterysta", "pięćset", "sześćset", "siedemset", "osiemset", "dziewięćset" };
protected static string[,] CONJUGATIONS = new string[,]
{
{ "", "", "" },
{ "tysiąc", "tysiące", "tysięcy" },
{ "milion" , "miliony" , "milionów" },
{ "miliard", "miliardy", "miliardów" },
{ "bilion" , "biliony" , "bilionow" },
{ "biliard", "biliardy", "biliardow" },
{ "trylion" , "tryliony", "trylionow" }
};
# endregion // Constant Arrays
# region Implementation
public static String DigitsStringToSpokenString(string input)
{
StringBuilder builder = new StringBuilder();
Int64 number = 0;
if (!Int64.TryParse(input, out number))
{
return input;
}
if (number < 0)
{
builder.Append("minus ");
number = -number;
}
Int64 sHundreds = 0;
Int64 dTens = 0;
Int64 jSingles = 0;
Int64 nTeens = 0;
Int64 gMagnitude = 0;
Int64 kConjugation = 0;
List<string> groups = new List<string>();
while (number != 0)
{
//get hundreds, tens and singles from a number to process
sHundreds = (number % 1000) / 100;
dTens = (number % 100) / 10;
jSingles = number % 10;
//check if teens form should be used
if (dTens == 1 && jSingles > 0)
{
nTeens = jSingles;
dTens = 0;
jSingles = 0;
}
else
{
nTeens = 0;
}
//choose conjugation form
if (jSingles == 1 && sHundreds + dTens + nTeens == 0)
{
kConjugation = 0;
}
else if (jSingles >= 2 && jSingles <= 4)
{
kConjugation = 1;
}
else
{
kConjugation = 2;
}
//add text if there is any houndred, ten, teen or single
if (sHundreds + dTens + nTeens + jSingles > 0)
{
if (sHundreds + dTens + nTeens == 0 && jSingles == 1 && !String.IsNullOrWhiteSpace(CONJUGATIONS[gMagnitude, kConjugation]))
{
// we do not say 'jeden tysiąc' but 'tysiąc'
jSingles = 0;
}
groups.Add(string.Format(" {0} {1} {2} {3} {4}", HUNDREDS[sHundreds], TENS[dTens], TEENS[nTeens], SINGLES[jSingles], CONJUGATIONS[gMagnitude, kConjugation]));
}
//process next three digits
gMagnitude++;
number = number / 1000;
}
groups.Reverse();
groups.ForEach(x => builder.Append(x));
string result = builder.ToString();
result = Regex.Replace(result, @"\s+", " ").Trim();
return result;
}
# endregion // Implementation
# region Example
static void Main(string[] args)
{
Console.WriteLine("-1000 => " + DigitsStringToSpokenString("-1000"));
Console.WriteLine("1000 => " + DigitsStringToSpokenString("1000"));
Console.WriteLine("-1 => " + DigitsStringToSpokenString("-1"));
Console.WriteLine("1 => " + DigitsStringToSpokenString("1"));
Console.WriteLine("123456789 => " + DigitsStringToSpokenString("123456789"));
Console.WriteLine("71351 => " + DigitsStringToSpokenString("71351"));
}
# endregion // Example
}
}

