zoukankan      html  css  js  c++  java
  • 新增3 把数字翻译为字符串

    题目要求:

      给定一个数字,按照如下规则翻译成字符串:0翻译成“a”,1翻译成“b”…25翻译成“z”。一个数字有多种翻译可能,例如12258一共有5种,分别是bccfi,bwfi,bczi,mcfi,mzi。实现一个函数,用来计算一个数字有多少种不同的翻译方法。

    思路:递归,遍历数字的位,当前位翻译一种方法,如果当前位和下一位能结合成另一种翻译,则有可记录为一种方法。但是递归会找出重复计算,如12258会计算1,2258和12,258,而2258会2,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.

    有重复,可以使用动态规划。从后往前求,比记录翻译方法数。

    //递归
    int getTransCount(const string & numstr, int i)
    {
        int len = numstr.size();
    
        //超过长度,只有一种可能
        if (i >= len - 1) {
            return 1;
        }
        //[i]和[i+1]可以组合成一个字符的,有两种方案
        if (i + 1 < len ) { int sum = (numstr[i] - '0') * 10 + numstr[i + 1] - '0'; if (sum > 9 && sum < 26) {
                return getTransCount(numstr,i+1) + getTransCount(numstr,i+2);
            }
        }
        //不能组合成一个字符的
        return getTransCount(numstr, i + 1);
    }
    //动态规划,从后往前,并记录
    int getTransCount(const string & numstr)
    {
        int len = numstr.size();
        vector  dp(len);
        int cur = 0;
        for (int i = len - 1; i >= 0; i--) {
            cur = 0;
            //当前数字为方法
            if (i < len - 1) {
                cur = dp[i + 1];
            }else{
                cur = 1;
            }
            //两个能不能组合成一个字符
            if (i < len - 1) { int sum = (numstr[i] - '0') * 10 + numstr[i + 1] - '0'; if (sum > 9 && sum < 26) {
                    if (i < len - 2) {
                        cur += dp[i + 2];
                    }
                    else {
                        cur += 1;
                    }
                }
            }
            dp[i] = cur;
        }
        return dp[0];
    }
    
    //获得数字的翻译组合
    int getTransCount(int number)
    {
        if (number < 0) {
            return 0;
        }
        string numstring = to_string(number);
        //递归方式
        //return getTransCount(numstring,0);
        //非递归方式
        return getTransCount(numstring);
    }
    
    //牛客网上没有该题目,对应测试如下
    //单元测试
    void test(char *testname, int index, int expect)
    {
        int result = getTransCount(index);
        if (result == expect) {
            cout << testname << " passed." << endl;
        }
        else {
            cout << testname << " failed." << endl;
        }
    
    }
    
    int main(void)
    {
        test("num0", 0, 1);
        test("num10", 10, 2);
        test("num126", 126, 2);
        test("num426", 426, 1);
        test("num12258", 12258, 5);
    
        return 0;
    }
    详细版本
    //动态规划,从后往前,并记录
    int getTransCount(const string & numstr)
    {
        int len = numstr.size();
        vector<int>  dp(len);
        int cur = 0;
        for (int i = len - 1; i >= 0; i--) {
            cur = 0;
            //当前数字为方法
            if (i < len - 1) {
                cur = dp[i + 1];
            }else{
                cur = 1;
            }
            //两个能不能组合成一个字符
            if (i < len - 1) { 
              int sum = (numstr[i] - '0') * 10 + numstr[i + 1] - '0';
              if (sum > 9 && sum < 26) {   if (i < len - 2) {   cur += dp[i + 2];   }   else {   cur += 1;    }   } } dp[i] = cur; } return dp[0]; } //获得数字的翻译组合 int getTransCount(int number) { if (number < 0) { return 0; } string numstring = to_string(number); return getTransCount(numstring); }
  • 相关阅读:
    MSP430F149学习之路——蓝牙模块
    MSP430F149学习之路——SPI
    MSP430推荐网站
    MSP430F149学习之路——UART
    MSP430F149学习之路——比较器Comparaor_A
    MSP430F149学习之路——PWM信号
    MSP430F149学习之路——捕获/比较模式
    MSP430F149学习之路——时钟1
    CUDA学习笔记(三)——CUDA内存
    CUDA学习笔记(一)——CUDA编程模型
  • 原文地址:https://www.cnblogs.com/dingxiaoqiang/p/8613474.html
Copyright © 2011-2022 走看看