You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在数字转英文单词算法中适配11-19的特殊数字处理

数字转英文单词算法:修复11-19数值处理问题

现有数字转英文单词的算法能正常处理除11-19之外的数字,但无法处理出现在数字首尾或中间的11-19这类数值,需在现有算法框架内解决该问题。

原实现代码:

int i = 0, multiplier = 1, length = nums.Length - 1;

string[] lessThanTwentyWords = new string[] { "One", "Two", "Three", "Four", "Five", "Six",
                                              "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve",
                                              "Thirteen", "Fourteen", "Fifteen", "Sixteen",
                                              "Seventeen", "Eighteen", "Nineteen"
                                            };
string[] tens = new string[] { "Ten", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" };

Dictionary<int, KeyValuePair<string, string[]>> posVsWordsMap = new Dictionary<int, KeyValuePair<string, string[]>>()
{
    [1] = new KeyValuePair<string, string[]>("", lessThanTwentyWords),
    [10] = new KeyValuePair<string, string[]>("", tens),
    [100] = new KeyValuePair<string, string[]>("Hundred", lessThanTwentyWords),
    [1000] = new KeyValuePair<string, string[]>("Thousand", lessThanTwentyWords),
    [10000] = new KeyValuePair<string, string[]>("", tens),
    [100000] = new KeyValuePair<string, string[]>("Hundred", lessThanTwentyWords),
    [1000000] = new KeyValuePair<string, string[]>("Million", lessThanTwentyWords),
    // 可继续补全更高位映射
};

string completeText = "";
for (var i = nums.Length - 1; i >= 0; i--)
{
    var number = nums[i];
    if (number != 0)
    {
        string text = posVsWordsMap[multiplier].Value[number - 1];
        var hundredsText = posVsWordsMap[multiplier].Key;
        multiplier *= 10;
        completeText += text + hundredsText;
    }
}

问题根源

原算法采用逐位单独处理逻辑,但11-19是两位一体的特殊数值,逐位拆分后会生成错误拼接结果(比如11会被拆成十位1和个位1,得到TenOne而非Eleven);同时存在拼写错误(Fourty应为Forty),且字符串拼接顺序是低位到高位,最终结果反向。

修复方案(基于现有框架调整)

  1. 增加特殊两位数判断:迭代处理十位级数位(乘数为10、10000等)时,优先检查当前位与下一位组成的数是否在11-19范围内,若是则直接取对应单词并跳过下一位迭代。
  2. 修正拼写与补全字典:修正tens数组的拼写错误,补全高位映射项。
  3. 调整拼接顺序:用列表收集结果片段,最后反转得到正确的高位到低位顺序。

修改后的完整代码

string NumberToWords(int number)
{
    if (number == 0) return "Zero";

    string[] lessThanTwentyWords = new string[] 
    { 
        "One", "Two", "Three", "Four", "Five", "Six",
        "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve",
        "Thirteen", "Fourteen", "Fifteen", "Sixteen",
        "Seventeen", "Eighteen", "Nineteen"
    };
    string[] tens = new string[] 
    { 
        "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", 
        "Seventy", "Eighty", "Ninety" 
    };

    // 数位映射:键为10的幂次,值为(数位后缀,对应单词数组)
    Dictionary<int, (string Suffix, string[] Words)> posVsWordsMap = new Dictionary<int, (string, string[])>()
    {
        [1] = ("", lessThanTwentyWords),
        [10] = ("", tens),
        [100] = ("Hundred", lessThanTwentyWords),
        [1000] = ("Thousand", lessThanTwentyWords),
        [10000] = ("", tens),
        [100000] = ("Hundred", lessThanTwentyWords),
        [1000000] = ("Million", lessThanTwentyWords),
        [10000000] = ("", tens),
        [100000000] = ("Hundred", lessThanTwentyWords)
    };

    List<string> parts = new List<string>();
    int remaining = number;
    int multiplier = 1;

    while (remaining > 0)
    {
        int digit = remaining % 10;
        remaining /= 10;

        if (digit == 0)
        {
            multiplier *= 10;
            continue;
        }

        // 处理十位级数位,检查是否组成11-19
        if (multiplier == 10 || multiplier == 10000 || multiplier == 10000000)
        {
            int twoDigit = digit * 10 + (remaining % 10);
            if (twoDigit >= 11 && twoDigit <= 19)
            {
                parts.Add(lessThanTwentyWords[twoDigit - 1]);
                remaining /= 10;
                multiplier *= 10;
            }
            else
            {
                parts.Add(tens[digit - 1] + posVsWordsMap[multiplier].Suffix);
            }
        }
        else
        {
            // 处理个位、百位等非十位级别
            parts.Add(posVsWordsMap[multiplier].Words[digit - 1] + posVsWordsMap[multiplier].Suffix);
        }

        multiplier *= 10;
    }

    parts.Reverse();
    return string.Join(" ", parts);
}

关键改动说明

  • 用List<string>收集结果片段,最后反转得到正确的高位到低位顺序,解决原代码拼接反向问题。
  • 在十位级数位处理中增加两位数判断,命中11-19范围时直接取对应单词并跳过下一位。
  • 修正tens数组拼写错误,用元组简化字典定义,提升可读性。
  • 增加0的特殊处理,符合数字转英文的常规逻辑。

内容的提问来源于stack exchange,提问作者Usman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:11:23