货币到单词拼写错误的问题

Posted

技术标签:

【中文标题】货币到单词拼写错误的问题【英文标题】:Currency to words mispelling problems 【发布时间】:2014-01-27 19:54:33 【问题描述】:

这是下面用于将数字转换为单词的代码。究竟是什么问题?英语的一切都很好,但在我的国家(罗马尼亚)有不同的拼写,让我们用几个例子来说明一下:

例如。 1 - 英语,一美元,一千,一百,两百你就是这样写的 罗马尼亚语,Un Dollar,O mie,O suta,Doua Sute,Trei Sute,单词上有复数变化,在英语中,几乎所有罗马尼亚语都使用 One,这会发生变化,我不知道如何修复这个复数.谢谢

private static string[] _ones =
            
                "",
                "unu",
                "doua",
                "trei",
                "patru",
                "cinci",
                "sase",
                "sapte",
                "opt",
                "noua"
            ;

            private static string[] _teens =
            
                "zece",
                "unsprezece",
                "doisprezece",
                "treisprezece",
                "paisprezece",
                "cincisprezece",
                "saisprezece",
                "saptisprezece",
                "optsprezece",
                "nouasprezece"
            ;

            private static string[] _tens =
            
                "",
                "zece",
                "douazeci",
                "treizeci",
                "patruzeci",
                "cincizeci",
                "saizeci",
                "saptezeci",
                "optzeci",
                "nouazeci"
            ;

            // US Nnumbering:
            private static string[] _thousands =
            
                "",
                "mie",
                "milion",
                "miliard",
                "trilion",
                "catralion"
            ;
    string digits, temp;
                bool showThousands = false;
                bool allZeros = true;

                // Use StringBuilder to build result
                StringBuilder builder = new StringBuilder();
                // Convert integer portion of value to string
                digits = ((long)value).ToString();
                // Traverse characters in reverse order
                for (int i = digits.Length - 1; i >= 0; i--)
                
                    int ndigit = (int)(digits[i] - '0');
                    int column = (digits.Length - (i + 1));

                    // Determine if ones, tens, or hundreds column
                    switch (column % 3)
                    
                        case 0:        // Ones position
                            showThousands = true;
                            if (i == 0)
                            
                                // First digit in number (last in loop)
                                temp = String.Format("0 ", _ones[ndigit]);
                            
                            else if (digits[i - 1] == '1')
                            
                                // This digit is part of "teen" value
                                temp = String.Format("0 ", _teens[ndigit]);
                                // Skip tens position
                                i--;
                            
                            else if (ndigit != 0)
                            
                                // Any non-zero digit
                                temp = String.Format("0 ", _ones[ndigit]);
                            
                            else
                            
                                // This digit is zero. If digit in tens and hundreds
                                // column are also zero, don't show "thousands"
                                temp = String.Empty;
                                // Test for non-zero digit in this grouping
                                if (digits[i - 1] != '0' || (i > 1 && digits[i - 2] != '0'))
                                    showThousands = true;
                                else
                                    showThousands = false;
                            

                            // Show "thousands" if non-zero in grouping
                            if (showThousands)
                            
                                if (column > 0)
                                
                                    temp = String.Format("012",
                                        temp,
                                        _thousands[column / 3],
                                        allZeros ? " " : ", ");
                                
                                // Indicate non-zero digit encountered
                                allZeros = false;
                            
                            builder.Insert(0, temp);
                            break;

                        case 1:        // Tens column
                            if (ndigit > 0)
                            
                                temp = String.Format("01",
                                    _tens[ndigit],
                                    (digits[i + 1] != '0') ? " si " : " ");
                                builder.Insert(0, temp);
                            
                            break;

                        case 2:        // Hundreds column
                            if (ndigit > 0)
                            
                                temp = String.Format("0 sute ", _ones[ndigit]);
                                builder.Insert(0, temp);
                            
                            break;
                    
                

                builder.AppendFormat("lei si 0:00 bani", (value - (long)value) * 100);


                // Capitalize first letter
                return String.Format("01",
                    Char.ToUpper(builder[0]),
                    builder.ToString(1, builder.Length - 1));

【问题讨论】:

sute 或 suta 是否只有 2 种可能性? (我问是因为在俄语中,还有更多;1 ticha;2 tichi;5 tisich;21 ticha)它变得复杂...... 一百 = o suta,超过一百(两百等)你说 doua sute,一千 = o mie,两千 = doua mii 这就是我想要的。 【参考方案1】:

你说过成百上千的情况只有两种:

数百个:1 = suta / 超过 1 = sute

千人:1 = mie / 超过 1 = mii

在这两种情况下,如果是单数,则使用“o”而不是“unu”来表示“一个”

基于此,您可以轻松地在代码中添加正确的条件。

我个人会重构这段代码,但因为这不是重点,所以我为你提供了一个解决方案。


数百个:

代替

case 2:        // Hundreds column
    if (ndigit > 0)
    
        temp = String.Format("0 sute ", _ones[ndigit]);
        builder.Insert(0, temp);
    

添加条件以检查数字并使用sute或suta:

case 2:        // Hundreds column
    if (ndigit > 0)
    
        temp = String.Format("0 1 ", ndigit == 1 ? "o" : _ones[ndigit], ndigit == 1 ? "suta" : "sute");
        builder.Insert(0, temp);
    

数千

而不是...

// Show "thousands" if non-zero in grouping
if (showThousands)

    if (column > 0)
    
        temp = String.Format("012",
            temp,
            _thousands[column / 3],
            allZeros ? " " : ", ");
    
    // Indicate non-zero digit encountered
    allZeros = false;

应该是:

// Show "thousands" if non-zero in grouping
if (showThousands)

    if (column > 0)
    
        bool isFirstThoussand = _thousands[column / 3] == _thousands[1] && ndigit == 1;

        temp = String.Format("012",
        isFirstThoussand ? "o " : temp,
        isFirstThoussand ? _thousands[1] : "mii",
        allZeros ? " " : ", ");
    
    // Indicate non-zero digit encountered
    allZeros = false;

...

这将根据您当前的参数产生所需的结果。


这是您的整个代码(包含此答案的更新)和一些测试内容:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RomanianNumberToWords

    class Program
    
        private static string[] _ones =
        
            "",
            "unu",
            "doua",
            "trei",
            "patru",
            "cinci",
            "sase",
            "sapte",
            "opt",
            "noua"
        ;

        private static string[] _teens =
        
            "zece",
            "unsprezece",
            "doisprezece",
            "treisprezece",
            "paisprezece",
            "cincisprezece",
            "saisprezece",
            "saptisprezece",
            "optsprezece",
            "nouasprezece"
        ;

        private static string[] _tens =
        
            "",
            "zece",
            "douazeci",
            "treizeci",
            "patruzeci",
            "cincizeci",
            "saizeci",
            "saptezeci",
            "optzeci",
            "nouazeci"
        ;

        // US Nnumbering:
        private static string[] _thousands =
        
            "",
            "mie",
            "milion",
            "miliard",
            "trilion",
            "catralion"
        ;

        
        static string MakeWordFromNumbers(decimal value)
        
            string digits, temp;
            bool showThousands = false;
            bool allZeros = true;

            // Use StringBuilder to build result
            StringBuilder builder = new StringBuilder();
            // Convert integer portion of value to string
            digits = ((long)value).ToString();
            // Traverse characters in reverse order
            for (int i = digits.Length - 1; i >= 0; i--)
            
                int ndigit = (int)(digits[i] - '0');
                int column = (digits.Length - (i + 1));

                // Determine if ones, tens, or hundreds column
                switch (column % 3)
                
                    case 0:        // Ones position
                        showThousands = true;
                        if (i == 0)
                        
                            // First digit in number (last in loop)
                            temp = String.Format("0 ", _ones[ndigit]);
                        
                        else if (digits[i - 1] == '1')
                        
                            // This digit is part of "teen" value
                            temp = String.Format("0 ", _teens[ndigit]);
                            // Skip tens position
                            i--;
                        
                        else if (ndigit != 0)
                        
                            // Any non-zero digit
                            temp = String.Format("0 ", _ones[ndigit]);
                        
                        else
                        
                            // This digit is zero. If digit in tens and hundreds
                            // column are also zero, don't show "thousands"
                            temp = String.Empty;
                            // Test for non-zero digit in this grouping
                            if (digits[i - 1] != '0' || (i > 1 && digits[i - 2] != '0'))
                                showThousands = true;
                            else
                                showThousands = false;
                        

                        // Show "thousands" if non-zero in grouping
                        if (showThousands)
                        
                            if (column > 0)
                            
                                bool isFirstThoussand = _thousands[column / 3] == _thousands[1] && ndigit == 1;

                                temp = String.Format("012",
                                    isFirstThoussand ? "o " : temp,
                                    isFirstThoussand ? _thousands[1] : "mii",
                                    allZeros ? " " : ", ");
                            
                            // Indicate non-zero digit encountered
                            allZeros = false;
                        
                        builder.Insert(0, temp);
                        break;

                    case 1:        // Tens column
                        if (ndigit > 0)
                        
                            temp = String.Format("01",
                                _tens[ndigit],
                                (digits[i + 1] != '0') ? " si " : " ");
                            builder.Insert(0, temp);
                        
                        break;

                    case 2:        // Hundreds column
                        if (ndigit > 0)
                        
                            temp = String.Format("0 1 ", ndigit == 1 ? "o" : _ones[ndigit], ndigit == 1 ? "suta" : "sute");
                            builder.Insert(0, temp);
                        
                        break;
                
            

            // You always need "lei" right?
            builder.AppendFormat("lei");

            // This code simply divides the decimal value by 1; and only adds "si NN bani" if there's a remainder
            if (Decimal.Remainder(value, 1) > 0) 
                builder.AppendFormat(" si 0:00 bani", (value - (long)value) * 100);
            

            // Capitalize first letter
            return String.Format("01",
                Char.ToUpper(builder[0]),
                builder.ToString(1, builder.Length - 1));
        

        static void Main(string[] args)
        
            Console.WriteLine(MakeWordFromNumbers(1127.00M));
            Console.WriteLine(MakeWordFromNumbers(2227.00M));

            Console.WriteLine(MakeWordFromNumbers(127.00M));
            Console.WriteLine(MakeWordFromNumbers(227.00M));

            Console.ReadKey();
        

        

【讨论】:

我已经告诉过你你是一个该死的神人你不相信我的代码运行完美,上帝保佑你。如果你善良的心可以告诉我如何修改,一千= Unu mie,我想要 O mie 而不是 'unu mie' 还有一百 = Unu suta 我想要 'o sua' 只有当它是一百或一千时才用 O 修改 Unu - O Suta,O mie,再次感谢你男人,我将标记为答案 @user3144640:已修复,请参阅更新后的答案。这段代码真的很丑,我想重写它,但今天没有时间! 请给我你的电子邮件,我有一家小公司+我需要做网站也许我会以某种方式回报你,我很感激。给我你的电子邮件,也许我们会保持联系。标记为答案 我的电子邮件在我的个人资料中:***.com/users/546000/david-khaykin;偿还任何东西的最佳方式总是用冷硬的现金! :)(不要忘记将最适合您情况的答案标记为答案) 哈哈哈好,一千的时候把千个'O'的代码放在哪里,就像你为一百个'O suta'做的那样?【参考方案2】:

在准备本地化应用程序时(翻译并将翻译应用于应用程序的行为),您将参与全球化的过程。

全球化是使我们的应用程序与翻译完美配合的过程。有一些准则需要记住。

    使用 resx(资源)文件 不要通过从部分字符串组装句子来偷工减料(就像您尝试做的那样)。你总会遇到语法问题!考虑一下德语问题,其中句子几乎是倒着的。 DO 使用数字 (1, 2, 3, 14, 1,000,000) 和缩写 (1mil, 1m 等) 等无语法结构来偷工减料。一般来说,这些都是通用的,尤其是在需要使用 SI 缩写的情况下。

【讨论】:

我不知道该怎么做,我只需要将用户在文本框中输入的一些数字转换为实际单词 我的意思是不要这样做。有太多数字无法正确翻译,您需要为应用程序支持的每种语言使用单独的算法。使用数字。【参考方案3】:

您需要跟踪数字的 [各种] 复数形式。

大多数语言只有两个语法数字:单数和复数,在谈论事物时只区分 1 和 many。

一些语言,显然包括罗马尼亚语,具有三个语法数字:单数、双数和复数,因此可以区分 1、2 和许多其他东西。

英语有点奇怪,因为在谈论数字时,我们通常不会将语法数字应用于单词:我们说“一百”、“两百”和“三百”。然而,为了与我们长期以来使用不一致的传统保持一致,在某些情况下和场景中它是允许的,人们可能会说“70 亿人死亡”之类的东西。但我离题了。

因此,将数字转换为单词的“通常”算法(3,792 到“三千七百九十二”)并不真正关心数字分组名称的语法数字或价值观。

对于这样的语言,您需要类似于二维矩阵的东西,其中行将部分的值映射到单词,而列则为指定的语法数字(单数、双数、复数)提供正确的单词形式。

【讨论】:

以上是关于货币到单词拼写错误的问题的主要内容,如果未能解决你的问题,请参考以下文章

实现处理拼写错误单词的 mongo db 搜索的最佳方法是啥?

如何搜索所有地图键c ++

5.贝叶斯算法单词拼写错误案例

技巧118 对你的工作进行拼写检查

机器学习之单词拼写检查

如何在Elasticsearch上搜索带或不带撇号的单词?并处理拼写错误?