数字翻译成字符串的可能性-题解

100 阅读3分钟

问题描述

小M需要一个程序来计算一个数字有多少种不同的翻译方法。翻译规则是:0对应"a",1对应"b",依此类推直到25对应"z"。这意味着每个数字可以独立翻译,而两位数则需要特别处理,因为它们可以作为一个整体(10-25)翻译,也可以分开翻译。

代码解析

1. 字符串转换

String numStr = String.valueOf(num);

这行代码将输入的整数num转换为字符串numStr,以便能够逐个字符地处理。

2. 动态规划数组初始化

int len = numStr.length();
int[] dp = new int[len + 1];
dp[0] = 1; // 初始化,空字符串有一种翻译方式

这里,我们初始化了一个长度为len + 1的动态规划数组dp,其中len是字符串numStr的长度。dp[0]被设置为1,表示空字符串有一种翻译方式。

3. 动态规划状态转移

for (int i = 1; i <= len; i++) {
    int single = dp[i - 1]; // 单个数字的翻译方式
    int doubleNum = 0;
    if (i > 1) {
        String twoDigit = numStr.substring(i - 2, i);
        if (twoDigit.charAt(0) == '1' || (twoDigit.charAt(0) == '2' && twoDigit.charAt(1) <= '5')) {
            doubleNum = dp[i - 2]; // 两位数字的翻译方式
        }
    }
    dp[i] = single + doubleNum; // 当前位置的翻译方式是单个和双个数字翻译方式的和
}

这个循环是动态规划的核心。对于字符串中的每个位置i,我们考虑两种情况:

  • 单个数字的翻译方式dp[i - 1]表示如果我们只考虑当前数字,那么有多少种翻译方式。这是通过递归地从dp[i - 1]获得的。
  • 两位数字的翻译方式doubleNum表示如果我们将当前数字和前一个数字作为一个两位数来考虑,有多少种翻译方式。这仅当两位数在10到25之间时才可能。我们通过检查twoDigit是否符合条件来确定doubleNum

dp[i]的值是singledoubleNum的和,这意味着对于每个位置,我们都有两种选择:要么将当前数字作为单个数字翻译,要么将当前数字和前一个数字作为一个两位数翻译。

4. 返回结果

return dp[len];

最后,dp[len]的值就是整个数字的所有可能翻译方式的数量,我们将其返回。

5. 主函数测试

public static void main(String[] args) {
    // You can add more test cases here
    System.out.println(solution(12258) == 5);
    System.out.println(solution(1400112) == 6);
    System.out.println(solution(1023) == 4);
}

main函数中,我们提供了几个测试用例来验证算法的正确性。这些测试用例覆盖了不同的输入情况,包括数字12258、1400112和1023。

注意事项

  • 在处理两位数字的翻译时,确保只考虑10到25之间的数字。
  • 在实际应用中,可能需要根据地区设置调整格式化逻辑,因为不同地区对数字格式的习惯可能不同。

通过这个练习,我们不仅学习了如何处理和格式化字符串,还了解了如何编写健壮的代码来处理不同的输入情况。这对于任何涉及数据处理的编程任务都是一个重要的技能。