数字转换成字符串

时间:2022-03-13 06:17:59

题目:给定一个数字,按照如下规则把它转化成字符串: 0 翻译成 a ,1 翻译成 b ,2 翻译成 c ,...... ,25 翻译成 z 。 一个数可能有多种翻译,比如数字 11 可以翻译成 bb 也可以翻译成 l ;例如数字 12258 有5 中不同的翻译 : bccfi 、bwfi 、bczi、mcfi 、mzi 这五种。我们现在输入 一个数字,计算这个数字一共有多少不同的翻译方法


思路:

一开始我也是懵逼的不知道如何下手,只能慢慢分析数字的特性。简单分析,0~9 这十个数分别对应前面 十个 字母,而 10~25, 因为是两位数,所以可以拆成两个字符,也可以合成一个字符,比如 11 可以是 bb 也可以是 l 。而当一个数大于 25 的时候,因为没有对应的字母,所以只能把它拆成当个的字母,这样情况就比较明了。

我们从数字的低位(右边)开始,以上面的 12258 为例,第一位是 8 只能对应 字母 i , 第二个子数字 5 ,

因为 58 > 25 所以只能是 是 f i 来表示,第三位 2 可以用 c 来表示 ,因为右边的5合起来是 25 可以用 z 表示也可以用 c f 表示,所以这时候就有两种表示的方法了。假如我们 用 z 来表示 25 ,那么剩下的左边两位数字 是 12,而且第三位的 2 已经同第二位的 5合在一起用 z 来表示了,所以此时 的 2 没法跟右边两位合起来表示其他字母;假如我们用 c f 表示 25 ,因为 2 是单独表示 c ,所以如果后面的第二位的 2 跟右边剩余的两个数字 12 合在一起表示,并不影响前面的表示。

倒这里我们可以得出 推导公式 : f(12258) = f(122) + f(12) . 接下来就是具体的实现了:根据上面的分析,我们知道需要用到当前数字的右边一个数字来跟 25 比较, 若比 25 大则只有一种表示方法,比25小(包括25)则有两种表示方法。分析到这已经很明显了,我们需要记录左边一位数字,然后利用递归来求解,具体代码:


private static int translation(int n) {
// TODO Auto-generated method stub
if(n < 10)
return 1;
int tp = n;
int pre = -1;
while(tp > 0){
int cur = tp%10;//对10 求余得到当前的数字 cur
if(pre == -1)//如果pre = -1 说明当前是右边第一个数字
pre = cur;
else{
if(cur*10 + pre <= 25){
return translation(tp) + translation(tp/10);
}
pre = cur;//将cur 赋给 pre,用以下次循环使用
}

tp = tp/10;
}
return 1;
}