Преобразование целых чисел в письменные числа
существует ли эффективный метод преобразования целого числа в записанные числа, например:
string Written = IntegerToWritten(21);
вернет "двадцать один".
есть ли способ сделать это, который не включает в себя массивную таблицу поиска?
12 ответов:
Это должно работать так:
public static class HumanFriendlyInteger { static string[] ones = new string[] { "", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" }; static string[] teens = new string[] { "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" }; static string[] tens = new string[] { "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }; static string[] thousandsGroups = { "", " Thousand", " Million", " Billion" }; private static string FriendlyInteger(int n, string leftDigits, int thousands) { if (n == 0) { return leftDigits; } string friendlyInt = leftDigits; if (friendlyInt.Length > 0) { friendlyInt += " "; } if (n < 10) { friendlyInt += ones[n]; } else if (n < 20) { friendlyInt += teens[n - 10]; } else if (n < 100) { friendlyInt += FriendlyInteger(n % 10, tens[n / 10 - 2], 0); } else if (n < 1000) { friendlyInt += FriendlyInteger(n % 100, (ones[n / 100] + " Hundred"), 0); } else { friendlyInt += FriendlyInteger(n % 1000, FriendlyInteger(n / 1000, "", thousands+1), 0); if (n % 1000 == 0) { return friendlyInt; } } return friendlyInt + thousandsGroups[thousands]; } public static string IntegerToWritten(int n) { if (n == 0) { return "Zero"; } else if (n < 0) { return "Negative " + IntegerToWritten(-n); } return FriendlyInteger(n, "", 0); } }
(отредактировано для исправления ошибки w / million, billion и т. д.)
Я использую эту удобную библиотеку под названием Humanizer.
https://github.com/Humanizr/Humanizer
Он поддерживает несколько культур и преобразует не только числа в слова, но и даты, и это очень простой в использовании.
вот как я его использую:
int someNumber = 543; var culture = System.Globalization.CultureInfo("en-US"); var result = someNumber.ToWords(culture); // 543 -> five hundred forty-three
и вуаля!
Я использую это code.It это код VB, но вы можете легко перевести его на C#. Это работает
Function NumberToText(ByVal n As Integer) As String Select Case n Case 0 Return "" Case 1 To 19 Dim arr() As String = {"One","Two","Three","Four","Five","Six","Seven", _ "Eight","Nine","Ten","Eleven","Twelve","Thirteen","Fourteen", _ "Fifteen","Sixteen","Seventeen","Eighteen","Nineteen"} Return arr(n-1) & " " Case 20 to 99 Dim arr() as String = {"Twenty","Thirty","Forty","Fifty","Sixty","Seventy","Eighty","Ninety"} Return arr(n -2) & " " & NumberToText(n Mod 10) Case 100 to 199 Return "One Hundred " & NumberToText(n Mod 100) Case 200 to 999 Return NumberToText(n0) & "Hundreds " & NumberToText(n mod 100) Case 1000 to 1999 Return "One Thousand " & NumberToText(n Mod 1000) Case 2000 to 999999 Return NumberToText(n00) & "Thousands " & NumberToText(n Mod 1000) Case 1000000 to 1999999 Return "One Million " & NumberToText(n Mod 1000000) Case 1000000 to 999999999 Return NumberToText(n00000) & "Millions " & NumberToText(n Mod 1000000) Case 1000000000 to 1999999999 Return "One Billion " & NumberTotext(n Mod 1000000000) Case Else Return NumberToText(n00000000) & "Billion " _ & NumberToText(n mod 1000000000) End Select End Function
вот код в c#
public static string AmountInWords(double amount) { var n = (int)amount; if (n == 0) return ""; else if (n > 0 && n <= 19) { var arr = new string[] { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" }; return arr[n - 1] + " "; } else if (n >= 20 && n <= 99) { var arr = new string[] { "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }; return arr[n / 10 - 2] + " " + AmountInWords(n % 10); } else if (n >= 100 && n <= 199) { return "One Hundred " + AmountInWords(n % 100); } else if (n >= 200 && n <= 999) { return AmountInWords(n / 100) + "Hundred " + AmountInWords(n % 100); } else if (n >= 1000 && n <= 1999) { return "One Thousand " + AmountInWords(n % 1000); } else if (n >= 2000 && n <= 999999) { return AmountInWords(n / 1000) + "Thousand " + AmountInWords(n % 1000); } else if (n >= 1000000 && n <= 1999999) { return "One Million " + AmountInWords(n % 1000000); } else if (n >= 1000000 && n <= 999999999) { return AmountInWords(n / 1000000) + "Million " + AmountInWords(n % 1000000); } else if (n >= 1000000000 && n <= 1999999999) { return "One Billion " + AmountInWords(n % 1000000000); } else { return AmountInWords(n / 1000000000) + "Billion " + AmountInWords(n % 1000000000); } }
У Джастина Роджерса есть класс" NumbersToEnglish", который должен делать эту работу за вас красиво!
начальная проводка.
http://weblogs.asp.net/justin_rogers/archive/2004/06/09/151675.aspxдоработанный исходный код
http://weblogs.asp.net/justin_rogers/articles/151757.aspxУ него есть немного внутренней таблицы поиска, но я действительно не знаю, как вы сможете уйти от этого.
почему массивная таблица поиска?
string GetWrittenInteger(int n) { string[] a = new string[] {"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" } string[] b = new string[] { "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" } string[] c = new string[] {"Twenty", "Thirty", "Forty", "Sixty", "Seventy", "Eighty", "Ninety"}; string[] d = new string[] {"Hundred", "Thousand", "Million"} string s = n.ToString(); for (int i = 0; i < s.Length; i++) { // logic (too lazy but you get the idea) } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace tryingstartfror4digits { class Program { static void Main(string[] args) { Program pg = new Program(); Console.WriteLine("Enter ur number"); int num = Convert.ToInt32(Console.ReadLine()); if (num <= 19) { string g = pg.first(num); Console.WriteLine("The number is " + g); } else if ((num >= 20) && (num <= 99)) { if (num % 10 == 0) { string g = pg.second(num / 10); Console.WriteLine("The number is " + g); } else { string g = pg.second(num / 10) + pg.first(num % 10); Console.WriteLine("The number is " + g); } } else if ((num >= 100) && (num <= 999)) { int k = num % 100; string g = pg.first(num / 100) +pg.third(0) + pg.second(k / 10)+pg.first(k%10); Console.WriteLine("The number is " + g); } else if ((num >= 1000) && (num <= 19999)) { int h = num % 1000; int k = h % 100; string g = pg.first(num / 1000) + "Thousand " + pg.first(h/ 100) + pg.third(k) + pg.second(k / 10) + pg.first(k % 10); Console.WriteLine("The number is " + g); } Console.ReadLine(); } public string first(int num) { string name; if (num == 0) { name = " "; } else { string[] arr1 = new string[] { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" , "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"}; name = arr1[num - 1]; } return name; } public string second(int num) { string name; if ((num == 0)||(num==1)) { name = " "; } else { string[] arr1 = new string[] { "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }; name = arr1[num - 2]; } return name; } public string third(int num) { string name ; if (num == 0) { name = ""; } else { string[] arr1 = new string[] { "Hundred" }; name = arr1[0]; } return name; } } }
это прекрасно работает от 1 до 19999 будет обновляться вскоре после его завершения
принятый ответ, похоже, не работает идеально. Он не обрабатывает тире в числах, таких как двадцать один, он не помещает Слово "и" для чисел, таких как "сто один", и, ну, это рекурсивно.
вот мой выстрел в ответ. Он добавляет слово" и " разумно и переносит числа соответствующим образом. Дайте мне знать, если какие-либо изменения необходимы.
вот как это назвать (очевидно, вы захотите поместить это в класс где-то):
for (int i = int.MinValue+1; i < int.MaxValue; i++) { Console.WriteLine(ToWords(i)); }
вот код:
private static readonly string[] Ones = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"}; private static readonly string[] Teens = { "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" }; private static readonly string[] Tens = { "", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }; public static string ToWords(int number) { if (number == 0) return "Zero"; var wordsList = new List<string>(); if (number < 0) { wordsList.Add("Negative"); number = Math.Abs(number); } if (number >= 1000000000 && number <= int.MaxValue) //billions { int billionsValue = number / 1000000000; GetValuesUnder1000(billionsValue, wordsList); wordsList.Add("Billion"); number -= billionsValue * 1000000000; if (number > 0 && number < 10) wordsList.Add("and"); } if (number >= 1000000 && number < 1000000000) //millions { int millionsValue = number / 1000000; GetValuesUnder1000(millionsValue, wordsList); wordsList.Add("Million"); number -= millionsValue * 1000000; if (number > 0 && number < 10) wordsList.Add("and"); } if (number >= 1000 && number < 1000000) //thousands { int thousandsValue = number/1000; GetValuesUnder1000(thousandsValue, wordsList); wordsList.Add("Thousand"); number -= thousandsValue * 1000; if (number > 0 && number < 10) wordsList.Add("and"); } GetValuesUnder1000(number, wordsList); return string.Join(" ", wordsList); } private static void GetValuesUnder1000(int number, List<string> wordsList) { while (number != 0) { if (number < 10) { wordsList.Add(Ones[number]); number -= number; } else if (number < 20) { wordsList.Add(Teens[number - 10]); number -= number; } else if (number < 100) { int tensValue = ((int) (number/10))*10; int onesValue = number - tensValue; if (onesValue == 0) { wordsList.Add(Tens[tensValue/10]); } else { wordsList.Add(Tens[tensValue/10] + "-" + Ones[onesValue]); } number -= tensValue; number -= onesValue; } else if (number < 1000) { int hundredsValue = ((int) (number/100))*100; wordsList.Add(Ones[hundredsValue/100]); wordsList.Add("Hundred"); number -= hundredsValue; if (number > 0) wordsList.Add("and"); } } }
здесь Консольное Приложение C# это вернет целые числа, а также десятичные числа.
расширение ответа Ника Масао для бенгальского числа той же проблемы. Начальный ввод числа находится в строке Юникода. Ура!!
string number = "২২৮৯"; number = number.Replace("০", "0").Replace("১", "1").Replace("২", "2").Replace("৩", "3").Replace("৪", "4").Replace("৫", "5").Replace("৬", "6").Replace("৭", "7").Replace("৮", "8").Replace("৯", "9"); double vtempdbl = Convert.ToDouble(number); string amount = AmountInWords(vtempdbl); private static string AmountInWords(double amount) { var n = (int)amount; if (n == 0) return " "; else if (n > 0 && n <= 99) { var arr = new string[] { "এক", "দুই", "তিন", "চার", "পাঁচ", "ছয়", "সাত", "আট", "নয়", "দশ", "এগার", "বারো", "তের", "চৌদ্দ", "পনের", "ষোল", "সতের", "আঠার", "ঊনিশ", "বিশ", "একুশ", "বাইস", "তেইশ", "চব্বিশ", "পঁচিশ", "ছাব্বিশ", "সাতাশ", "আঠাশ", "ঊনত্রিশ", "ত্রিশ", "একত্রিস", "বত্রিশ", "তেত্রিশ", "চৌত্রিশ", "পঁয়ত্রিশ", "ছত্রিশ", "সাঁইত্রিশ", "আটত্রিশ", "ঊনচল্লিশ", "চল্লিশ", "একচল্লিশ", "বিয়াল্লিশ", "তেতাল্লিশ", "চুয়াল্লিশ", "পয়তাল্লিশ", "ছিচল্লিশ", "সাতচল্লিশ", "আতচল্লিশ", "উনপঞ্চাশ", "পঞ্চাশ", "একান্ন", "বায়ান্ন", "তিপ্পান্ন", "চুয়ান্ন", "পঞ্চান্ন", "ছাপ্পান্ন", "সাতান্ন", "আটান্ন", "উনষাট", "ষাট", "একষট্টি", "বাষট্টি", "তেষট্টি", "চৌষট্টি", "পয়ষট্টি", "ছিষট্টি", " সাতষট্টি", "আটষট্টি", "ঊনসত্তর ", "সত্তর", "একাত্তর ", "বাহাত্তর", "তেহাত্তর", "চুয়াত্তর", "পঁচাত্তর", "ছিয়াত্তর", "সাতাত্তর", "আটাত্তর", "ঊনাশি", "আশি", "একাশি", "বিরাশি", "তিরাশি", "চুরাশি", "পঁচাশি", "ছিয়াশি", "সাতাশি", "আটাশি", "উননব্বই", "নব্বই", "একানব্বই", "বিরানব্বই", "তিরানব্বই", "চুরানব্বই", "পঁচানব্বই ", "ছিয়ানব্বই ", "সাতানব্বই", "আটানব্বই", "নিরানব্বই" }; return arr[n - 1] + " "; } else if (n >= 100 && n <= 199) { return AmountInWords(n / 100) + "এক শত " + AmountInWords(n % 100); } else if (n >= 100 && n <= 999) { return AmountInWords(n / 100) + "শত " + AmountInWords(n % 100); } else if (n >= 1000 && n <= 1999) { return "এক হাজার " + AmountInWords(n % 1000); } else if (n >= 1000 && n <= 99999) { return AmountInWords(n / 1000) + "হাজার " + AmountInWords(n % 1000); } else if (n >= 100000 && n <= 199999) { return "এক লাখ " + AmountInWords(n % 100000); } else if (n >= 100000 && n <= 9999999) { return AmountInWords(n / 100000) + "লাখ " + AmountInWords(n % 100000); } else if (n >= 10000000 && n <= 19999999) { return "এক কোটি " + AmountInWords(n % 10000000); } else { return AmountInWords(n / 10000000) + "কোটি " + AmountInWords(n % 10000000); } }
следующий код консольного приложения C# принимает денежное значение в числах до 2 десятичных знаков и печатает его на английском языке. Это не только преобразует целое число в его английский эквивалент, но и в денежном выражении в долларах и центах.
namespace ConsoleApplication2 { using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; class Program { static void Main(string[] args) { bool repeat = true; while (repeat) { string inputMonetaryValueInNumberic = string.Empty; string centPart = string.Empty; string dollarPart = string.Empty; Console.Write("\nEnter the monetary value : "); inputMonetaryValueInNumberic = Console.ReadLine(); inputMonetaryValueInNumberic = inputMonetaryValueInNumberic.TrimStart('0'); if (ValidateInput(inputMonetaryValueInNumberic)) { if (inputMonetaryValueInNumberic.Contains('.')) { centPart = ProcessCents(inputMonetaryValueInNumberic.Substring(inputMonetaryValueInNumberic.IndexOf(".") + 1)); dollarPart = ProcessDollar(inputMonetaryValueInNumberic.Substring(0, inputMonetaryValueInNumberic.IndexOf("."))); } else { dollarPart = ProcessDollar(inputMonetaryValueInNumberic); } centPart = string.IsNullOrWhiteSpace(centPart) ? string.Empty : " and " + centPart; Console.WriteLine(string.Format("\n\n{0}{1}", dollarPart, centPart)); } else { Console.WriteLine("Invalid Input.."); } Console.WriteLine("\n\nPress any key to continue or Escape of close : "); var loop = Console.ReadKey(); repeat = !loop.Key.ToString().Contains("Escape"); Console.Clear(); } } private static string ProcessCents(string cents) { string english = string.Empty; string dig3 = Process3Digit(cents); if (!string.IsNullOrWhiteSpace(dig3)) { dig3 = string.Format("{0} {1}", dig3, GetSections(0)); } english = dig3 + english; return english; } private static string ProcessDollar(string dollar) { string english = string.Empty; foreach (var item in Get3DigitList(dollar)) { string dig3 = Process3Digit(item.Value); if (!string.IsNullOrWhiteSpace(dig3)) { dig3 = string.Format("{0} {1}", dig3, GetSections(item.Key)); } english = dig3 + english; } return english; } private static string Process3Digit(string digit3) { string result = string.Empty; if (Convert.ToInt32(digit3) != 0) { int place = 0; Stack<string> monetaryValue = new Stack<string>(); for (int i = digit3.Length - 1; i >= 0; i--) { place += 1; string stringValue = string.Empty; switch (place) { case 1: stringValue = GetOnes(digit3[i].ToString()); break; case 2: int tens = Convert.ToInt32(digit3[i]); if (tens == 1) { if (monetaryValue.Count > 0) { monetaryValue.Pop(); } stringValue = GetTens((digit3[i].ToString() + digit3[i + 1].ToString())); } else { stringValue = GetTens(digit3[i].ToString()); } break; case 3: stringValue = GetOnes(digit3[i].ToString()); if (!string.IsNullOrWhiteSpace(stringValue)) { string postFixWith = " Hundred"; if (monetaryValue.Count > 0) { postFixWith = postFixWith + " And"; } stringValue += postFixWith; } break; } if (!string.IsNullOrWhiteSpace(stringValue)) monetaryValue.Push(stringValue); } while (monetaryValue.Count > 0) { result += " " + monetaryValue.Pop().ToString().Trim(); } } return result; } private static Dictionary<int, string> Get3DigitList(string monetaryValueInNumberic) { Dictionary<int, string> hundredsStack = new Dictionary<int, string>(); int counter = 0; while (monetaryValueInNumberic.Length >= 3) { string digit3 = monetaryValueInNumberic.Substring(monetaryValueInNumberic.Length - 3, 3); monetaryValueInNumberic = monetaryValueInNumberic.Substring(0, monetaryValueInNumberic.Length - 3); hundredsStack.Add(++counter, digit3); } if (monetaryValueInNumberic.Length != 0) hundredsStack.Add(++counter, monetaryValueInNumberic); return hundredsStack; } private static string GetTens(string tensPlaceValue) { string englishEquvalent = string.Empty; int value = Convert.ToInt32(tensPlaceValue); Dictionary<int, string> tens = new Dictionary<int, string>(); tens.Add(2, "Twenty"); tens.Add(3, "Thirty"); tens.Add(4, "Forty"); tens.Add(5, "Fifty"); tens.Add(6, "Sixty"); tens.Add(7, "Seventy"); tens.Add(8, "Eighty"); tens.Add(9, "Ninty"); tens.Add(10, "Ten"); tens.Add(11, "Eleven"); tens.Add(12, "Twelve"); tens.Add(13, "Thrteen"); tens.Add(14, "Fourteen"); tens.Add(15, "Fifteen"); tens.Add(16, "Sixteen"); tens.Add(17, "Seventeen"); tens.Add(18, "Eighteen"); tens.Add(19, "Ninteen"); if (tens.ContainsKey(value)) { englishEquvalent = tens[value]; } return englishEquvalent; } private static string GetOnes(string onesPlaceValue) { int value = Convert.ToInt32(onesPlaceValue); string englishEquvalent = string.Empty; Dictionary<int, string> ones = new Dictionary<int, string>(); ones.Add(1, " One"); ones.Add(2, " Two"); ones.Add(3, " Three"); ones.Add(4, " Four"); ones.Add(5, " Five"); ones.Add(6, " Six"); ones.Add(7, " Seven"); ones.Add(8, " Eight"); ones.Add(9, " Nine"); if (ones.ContainsKey(value)) { englishEquvalent = ones[value]; } return englishEquvalent; } private static string GetSections(int section) { string sectionName = string.Empty; switch (section) { case 0: sectionName = "Cents"; break; case 1: sectionName = "Dollars"; break; case 2: sectionName = "Thousand"; break; case 3: sectionName = "Million"; break; case 4: sectionName = "Billion"; break; case 5: sectionName = "Trillion"; break; case 6: sectionName = "Zillion"; break; } return sectionName; } private static bool ValidateInput(string input) { return Regex.IsMatch(input, "[0-9]{1,18}(\.[0-9]{1,2})?")) } } }
просто получить эту строку и конвертировать с помощью как строка s=txtNumber.Текст.Метод toString(); int i=преобразование.ToInt32(s. Tostring()); он будет писать только полное целое значение
только для турецкого представления класса HumanFriendlyInteger ( ↑ ) (Türkçe, sayı yazı karşılığı):
public static class HumanFriendlyInteger { static string[] ones = new string[] { "", "Bir", "İki", "Üç", "Dört", "Beş", "Altı", "Yedi", "Sekiz", "Dokuz" }; static string[] teens = new string[] { "On", "On Bir", "On İki", "On Üç", "On Dört", "On Beş", "On Altı", "On Yedi", "On Sekiz", "On Dokuz" }; static string[] tens = new string[] { "Yirmi", "Otuz", "Kırk", "Elli", "Altmış", "Yetmiş", "Seksen", "Doksan" }; static string[] thousandsGroups = { "", " Bin", " Milyon", " Milyar" }; private static string FriendlyInteger(int n, string leftDigits, int thousands) { if (n == 0) { return leftDigits; } string friendlyInt = leftDigits; if (friendlyInt.Length > 0) { friendlyInt += " "; } if (n < 10) friendlyInt += ones[n]; else if (n < 20) friendlyInt += teens[n - 10]; else if (n < 100) friendlyInt += FriendlyInteger(n % 10, tens[n / 10 - 2], 0); else if (n < 1000) friendlyInt += FriendlyInteger(n % 100, ((n / 100 == 1 ? "" : ones[n / 100] + " ") + "Yüz"), 0); // Yüz 1 ile başlangıçta "Bir" kelimesini Türkçe'de almaz. else friendlyInt += FriendlyInteger(n % 1000, FriendlyInteger(n / 1000, "", thousands + 1), 0); return friendlyInt + thousandsGroups[thousands]; } public static string IntegerToWritten(int n) { if (n == 0) return "Sıfır"; else if (n < 0) return "Eksi " + IntegerToWritten(-n); return FriendlyInteger(n, "", 0); }