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

为何Memoization未能加速整数转英文单词的递归程序?

为啥Memoization优化整数转英文单词递归没提升性能?

根本原因:递归逻辑无重复计算

你当前的递归是按数位层级拆分数字,比如处理123456789时,会拆成123*1000000 + 456789,再分别处理123和456789,每个子问题的num参数都是唯一的,几乎不会出现同一个数字被多次计算的情况。Memoization的核心是缓存重复计算的结果,这里没有重复计算,加了字典缓存反而多了读写开销,自然性能没提升甚至更慢。

你的Memoization实现有冗余操作

带缓存的代码里,先调用ContainsKey再调用TryGetValue是重复查询,TryGetValue本身就能判断键是否存在,可以简化:

// 原冗余代码
if (memoizationDictionary.ContainsKey(num))
{
    if( memoizationDictionary.TryGetValue(num, out var memoizedResult))
    {
        return memoizedResult;
    }
}

// 优化后
if (memoizationDictionary.TryGetValue(num, out var memoizedResult))
{
    return memoizedResult;
}

额外小问题

tens数组里的"Fourty"是拼写错误,正确应为"Forty"。


带Memoization的代码

Dictionary<long, string> memoizationDictionary = new Dictionary<long, string>();

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

string ConvertNumsToWords(long num, string[] lessThanTwentyWords, string[] tens)
{
    long result = 1;
    long rem = 0;

    // Check if the result is already memoized
    if (memoizationDictionary.ContainsKey(num))
    {
        if( memoizationDictionary.TryGetValue(num, out var memoizedResult))
        {
            return memoizedResult;
        }
    }

    if (num == 0)
        return "";

    if (num >= 1 && num < 20)
    {
        memoizationDictionary[num] = lessThanTwentyWords[num];
        return memoizationDictionary[num];
    }

    if ((num / 1000000000) > 0)
    {
        rem = num % 1000000000;
        result = num / 1000000000;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Billion" + 
                                     (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
        return memoizationDictionary[num];
    }

    if ((num / 1000000) > 0)
    {
        rem = num % 1000000;
        result = num/1000000;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Million" + 
                                     (rem != 0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
        return memoizationDictionary[num];
    }

    if ((num / 1000) > 0)
    {
        rem = num % 1000;
        result = num/ 1000;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " +"Thousand" + 
                                     (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
        return memoizationDictionary[num];
    }

    if ((num / 100) > 0)
    {
        rem = num % 100;
        result = num/100;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Hundred" + 
                                     (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
        return memoizationDictionary[num];
    }
    else
    {
        if (num >= 20)
        {
            memoizationDictionary[num] = tens[num / 10] + (num % 10 != 0 ? (" " + lessThanTwentyWords[num % 10]) : "");
            return memoizationDictionary[num];
        }
        return "";
    }    
}

普通递归代码

string ConvertNumsToWords(long num, string[] lessThanTwentyWords, string[] tens)
{
    long result = 1;
    long rem = 0;

    if (num == 0)
        return "";

    if (num >= 1 && num < 20)
        return lessThanTwentyWords[num];

    if ((num / 1000000000) > 0)
    {
        rem = num % 1000000000;
        result = num / 1000000000;

        return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Billion" + (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
    }

    if ((num / 1000000) > 0)
    {
        rem = num % 1000000;
        result = num/1000000;

        return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Million" + (rem != 0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");        
    }

    if ((num / 1000) > 0)
    {
        rem = num % 1000;
        result = num/ 1000;

        return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " +"Thousand" + (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
    }

    if ((num / 100) > 0)
    {
        rem = num % 100;
        result = num/100;

        return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Hundred" + (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
    }
    else
    {
        if (num >= 20)
        {            
            return tens[num / 10] + (num % 10 != 0 ? (" " + lessThanTwentyWords[num % 10]) : "");
        }
        return "";
    }    
}

内容的提问来源于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 10:35:56