把数字翻译成字符串

文章介绍了如何将数字编码为26个英文字母,并提供了一种解决解码问题的思路,即转化为跳台阶问题。对于输入的数字串,需要考虑单个字符编码和两个字符合并编码的情况,同时处理0和大于26的数值的特殊情况。给出了递归算法实现,计算不同解码方式的数量。
摘要由CSDN通过智能技术生成

把数字翻译成字符串

问题描述

有一种将字母编码成数字的方式:‘a’->1, ‘b->2’, … , ‘z->26’。
现在给一串数字,返回有多少种可能的译码结果

示例1

输入:“12”
返回值:2
说明:2种可能的译码结果(”ab” 或”l”)

示例2

输入:“31717126241541717”
返回值:192
说明:192种可能的译码结果

解题思路

首先思考如何去编码。

  1. 只有1-26可以进行编码,所以只考虑单个字符编码,或者两个字符合并编码,这就将问题转换成跳台阶问题(每次可以上一个或者两个台阶)。

  2. 但是编码的数值范围是有要求的,只能匹配1-26,对其他数值要进行特殊处理

    • 针对0

    <1> 0在首位出现,只有0种译码结果
    eg:0×,01×,011×
    <2> 0在其他位置,只能去考虑它所在的前一位和0组合后再进行匹配,而两位中含有0的数值只有10,20。
    故此,0的前一位只能是1或2且视为一种译码结果;其他均为0种译码结果
    eg:30×,40×,100×,1030×,10√,20√,1020√

    • 针对大于26的数值

    <1> 只能将其当单个字符处理 36->3和6
    <2> 所以按照3去找最长字串时,遇到大于26时,需要停止查找并进行分割。1236->123和6

  3. 划分字符串,找字串满足可以单个匹配,也可两个匹配,它的编译结果就转成对应长度的跳台阶结果。从当前位置(第i位)往后寻找满足(第i位和第i+1位对应的数字小于等于26)条件的字长字串。
    在这里插入图片描述

过程求解

长度为n的符合条件的字串的译码种类数

public int getTotal(int num) {
    if (num == 1)
        return 1;
    if (num == 2)
        return 2;
    return getTotal(num - 1) + getTotal(num - 2);
}

对字符串进行分段处理

public int solve (String nums) {
    if (nums.length() <= 2) {//对长度小于等于2的字符串进行处理
        int n1 = Integer.parseInt(nums);
        if (n1 == 0)
            return 0;
        if (n1 % 10 == 0 && n1 / 10 > 2)
            return 0;
        else if (n1 <= 10 || n1 > 26 || n1 == 20)
            return 1;
        else
            return 2;
    }
    int m = 1;
    for (int i = 0; i < nums.length(); i++) {
        int begin = i;
        if (nums.charAt(i) == '0') {
            if (i - 1 < 0)//是否是以0为首位
                return 0;
            int u = nums.charAt(i - 1) - 48;
            if (u == 0 || u > 2)//上一位是否符合条件
                return 0;
        } else if (i + 1 < nums.length() && nums.charAt(i + 1) == '0') {//i+1位为0
            int u = nums.charAt(i) - 48;
            if (u == 0 || u > 2)//当前位是否符合条件
                return 0;
            i++} else {
            //找满足条件的最长子串
            while (i < nums.length() - 1 &&
                   Integer.parseInt(nums.substring(i, i + 2)) <= 26) {
                if (i + 2 < nums.length() && nums.charAt(i + 2) == '0')//判断是否结束寻找
                    break;
                i++;
            }
            m *= getTotal(i - begin + 1);
        }
    }
    return m;
}

当然代码中还有可优化的地方,也可能存在一些问题,欢迎指正。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值