把数字翻译成字符串

题目描述

        给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成‘a’,1翻译成‘b’,……,11翻译成‘l’,……,25翻译成‘z’。一个数值可能翻译成多个字符串。例如:12258有5种不同的翻译,分别是“bccfi”、“bwfi”、“bczi”、“mcfi”、“mzi”。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。


        以12258为例分析,如何从数字的第一位开始一步步计算不同翻译方法的数目。有两种不同的选择来翻译第一位数字1 。第一种是选择是数字1单独翻译成‘b’ ,剩下的数字为2258;第二种是1和紧挨着的2一起翻译成‘m’,后面剩下数字258 。
        当最开始的一个或者两个数字被翻译成一个字符后,接着翻译后面剩下的数字,这样就变成了一个简单的递归问题,有点像以前做过的青蛙跳台阶。显然,可以用一个递归函数来计算翻译的数目。
        定义函数f(i)表示从第i位数字开始的不同翻译的数目,那么f(i)=f(i+1)+g(i,i+1)×f(i+2)。当第i位和第i+1位两位数字拼接起来的数字在10~25范围之内时,g(i,i+1)的值为1,否则为0 。
        虽然用递归来分析问题,但是由于存在重复存在的子问题,因此此思路不是最优。依然以12258为例,翻译12258可以分解成两个子问题:1和2258,以及翻译12和258 。接下来翻译第一个子问题中剩下的2和258,可以发现,这个时候258就重复出现了。
        递归从最大的问题开始自上而下解决问题。我们也可以从最小的子问题开始自下而上解决问题,这样就可以消除重复的子问题。即从数字的末尾开始,从右到左的翻译并计算不同翻译的数目。
以下为参考代码:

using System;

namespace 把数字翻译成字符串
{
    class Program
    {
        static void Main(string[] args)
        {
            Solution s = new Solution();
            int num1 = 12258;
            int num2 = 126525;
            int num3 = -1;
            int num4 = 0;
            Console.WriteLine("Test1:\n{0}\t" + s.TranslateNumber(num1), num1);
            Console.WriteLine("Test2:\n{0}\t" + s.TranslateNumber(num2), num2);
            Console.WriteLine("Test3:\n{0}\t" + s.TranslateNumber(num3), num3);
            Console.WriteLine("Test4:\n{0}\t" + s.TranslateNumber(num4), num4);
        }
    }

    class Solution
    {

        public int TranslateNumber(int number)
        {
            if (number < 0)
                return 0;

            string num = number.ToString();

            return TranslateNumber(num);
        }

        private int TranslateNumber(string number)
        {
            int length = number.Length;
            int count = 0;                  //统计有多少种可翻译的方法
            int[] counts = new int[length];

            for (int i = length-1; i >= 0; i--)
            {
                if (i < length-1)
                    count = counts[i + 1];
                else
                    count = 1;

                if (i < length-1)
                {
                    int digit1 = number[i] - '0';
                    int digit2 = number[i + 1] - '0';
                    int num = 10 * digit1 + digit2;

                    if (num >= 10 && num <= 25)
                    {
                        if (i < length - 2)
                            count += counts[i + 2];
                        else
                            count += 1;
                    }
                }
                counts[i] = count;
            }
            count = counts[0];

            return count;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_33575542/article/details/80927830