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

题目:

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

解题思路:

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

f ( i ) = f ( i + 1 ) + f ( i + 2 ) g ( i , i + 1 )
。其中当第 i 位和第 i + 1 位组合到一起可以翻译的时候(即在10~25的范围内), 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;                                 
}

程序运行结果:

程序运行结果

猜你喜欢

转载自blog.csdn.net/m0_37950361/article/details/80654162