c# - 暗黙的に変換できません - vb.net null 0 変換




整数を書かれた数字に変換する (8)

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

そしてほら!

整数を書かれた数字に変換する効率的な方法はありますか、例えば:

string Written = IntegerToWritten(21);

「Twenty One」を返します。

大規模なルックアップテーブルを必要としないこれを行う方法はありますか?


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);
    }

これはかなりうまくいくはずです:

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);
    }
}

(100万、10億などのバグを修正するために編集)


その文字列を取得し、文字列s = txtNumber.Text.Tostring();のように変換します。 int i = Convert.ToInt32(s.Tostring()); 完全な整数値のみを書き込みます



受け入れられた答えは完全に機能しないようです。 これは、21のような数字のダッシュを処理せず、「100」のような数字の「と」という単語を入れません。また、再帰的です。

これが私の答えです。 「and」という単語をインテリジェントに追加し、数字を適切にハイフネーションします。 変更が必要かどうかを教えてください。

これを呼び出す方法は次のとおりです(明らかに、これをどこかのクラスに配置する必要があります)。

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#コンソールアプリコードは、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})?"))
        }
    }
}

私はこのコードを使用します。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\10 -2) & " " & NumberToText(n Mod 10)

Case 100 to 199
  Return "One Hundred " & NumberToText(n Mod 100)

Case 200 to 999
  Return NumberToText(n\100) & "Hundreds " & NumberToText(n mod 100)

Case 1000 to 1999
  Return "One Thousand " & NumberToText(n Mod 1000)

Case 2000 to 999999
  Return NumberToText(n\1000) & "Thousands " & NumberToText(n Mod 1000)

Case 1000000 to 1999999
  Return "One Million " & NumberToText(n Mod 1000000)

Case 1000000 to 999999999
  Return NumberToText(n\1000000) & "Millions " & NumberToText(n Mod 1000000)

Case 1000000000 to 1999999999
  Return "One Billion " & NumberTotext(n Mod 1000000000)

Case Else
  Return NumberToText(n\1000000000) & "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);
        }
    }




integer