【剑指offer】面试题46:把数字翻译成字符串【C++版本】

40 篇文章 1 订阅

总结的部分题目思路与代码,待完善。
【剑指offer-第二版】部分题目与解答【C++版本】

题目:

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

解题思路:

1.使用动态规划的思路来进行求解。
2.确定子问题:以12258为例子,求解12258有多少种翻译方法,可以分解为两个子问题,第一个子问题为’1’单独翻译和”2258”翻译,第二个为”12”联合翻译,”258”进行翻译。这样就等于求解”2258”和”258”一共有多少中翻译方法,以此类推。
这里写图片描述
3.确定转移方程: f(i)  f ( i ) 代表从第i位数字开始不同翻译的数目,那么

f(i)=f(i+1)+f(i+2)g(i,i+1)  f ( i ) = f ( i + 1 ) + f ( i + 2 ) ∗ g ( i , i + 1 )
。其中当第 i  i 位和第i+1位组合到一起可以翻译的时候(即在10~25的范围内), g(i,i+1)  g ( i , i + 1 ) 等于1,否则等于0。
4.尽量避免重复的子问题,选择使用自下而上、从小到达的方法来解决。把子问题的结果记录下来,用于计算下一次更大的问题。

//和《剑指offer》原解法略不同的方法

仍然使用动态规划的方法,剑指offer是从数字的末尾开始计算的,我们也可以从数字的开头开始计算。以12258为例子:
1.设f(i)为从高位开始的前i位数字可以翻译的方法数。f(0) = 1 且f(1) = 1
2.从i = 1开始,如果f(i)和f(i-1)组合起来可以一起翻译,那么f(i) = f(i-1)+f(i-2),否则f(i) = f(i-1)

#include <vector>                             
#include <string>                             
#include <stdlib.h>                           
#include <iostream>                           
#include <algorithm>                          

using namespace std;                          

//记录用的数组,初始化f(0) = 1,f(1) = 1       
int cnt[70] = {1,1};                          

int getTranslationCnt(int num)                
{                                             
    if(num < 0)return 0;                      

    //转换成为string来处理                    
    string numS = to_string(num);             
    int numSize = numS.size();                
    //从i=1,即从左到右第2个数字开始进行计算  
    for(int i = 1;i != numSize;i++){          
        //如果前一个数字是1,那么和当前数字总是能合并翻译     
        //所以f(i) = f(i-1)+f(i-2)            
        if(numS[i-1] == '1'){                 
            cnt[i+1] = cnt[i] + cnt[i-1];     
        }                                     
        //如果前一个数字是2,那么只有当前数字是0~5才能合并翻译
        else if(numS[i-1] == '2'){            
            if(numS[i] >= '0' && numS[i] <= '5'){
                cnt[i+1] = cnt[i] + cnt[i-1]; 
            }                                 
            else{                             
                cnt[i+1] = cnt[i];            
            }                                 
        }                                     
        //前一个数字是其他数字,都不能合并翻译                                                                                                                                                                                              
        else{                                 
            cnt[i+1] = cnt[i];                
        }                                     
    }                                         

    return cnt[numSize];                      
}                                             

int main()                                    
{                                             
    cout << "Please enter a posi integer:" << endl;           
    int test;                                 
    while(cin >> test){                       
        cout << "The translation cnts are: " << getTranslationCnt(test) << endl;

        //输入ctrl+d来退出,linux下的退出                        
        cout << "Please enter a posi integer(ctrl+d to quit):" << endl;
    }                                         

    return 0;                                 
}

程序运行结果:

程序运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值