规定1和A对应,2和B对应,3和C对应…那么一个数字字符串比如“111”,就可以转化为“AAA”,“KA”和"AK"。 给定一个只有数字字符串组成的字符串str,返回有多少种转化结果.
package com.fll.test.nummber_string;
import java.util.ArrayList;
import java.util.List;
public class NumberStringMain {
/**
* 规定1和A对应,2和B对应,3和C对应…那么一个数字字符串比如“111”,就可以转化为“AAA”,“KA”和“AK”。
* 给定一个只有数字字符串组成的字符串str,返回有多少种转化结果。
*/
public static void main(String[] args) {
String str = "12345614231";
NumberStringMain numberStringMain = new NumberStringMain();
int number = numberStringMain.number(str);
System.out.println(number);
List<String> list = new ArrayList<>();
int numberExchange = numberStringMain.numberExchange(str, list);
System.out.println(numberExchange);
}
public int numberExchange(String str , List<String> list){
if(str==null||str.length()==0){
return 0;
}
return processSubStr(str.toCharArray() ,0 , list);
}
//i之前的位置,如何转化已经做过决定
//i...有多少种转化结果
public int processSubStr(char[] str, int i , List<String> list){
//说明这一条路走到头了 所以算作一种结果
if(i == str.length){
System.out.println(list);
return 1;
}
// 如果某一次递归调用 i 指向的直接是 0
// 因为 0 不可以转为一个字母 所以本条路不算做一种结果
if(str[i] == '0'){
return 0;
}
if(str[i] == '1'){
//如果 i位置是1 有两种情况 i位置的数字单独转为一个字母 或者 i和i+1合起来转为一个字母
List list1 = new ArrayList();
list1.addAll(list);
char exchangeChar = exchangeChar(Integer.parseInt(String.valueOf(str[i])));
list1.add(exchangeChar);
System.out.println(String.format("第 %s 位置的 %s 转为 %s" , i , str[i] , exchangeChar));
int n_1_num = processSubStr(str , i + 1 , list1);
if(i + 1 < str.length){
List list2 = new ArrayList();
list2.addAll(list);
char exchangeChar1 = exchangeChar(Integer.parseInt(String.valueOf(str[i] + "" + str[i + 1])));
list2.add(exchangeChar1);
System.out.println(String.format("第 %s%S 位置的 %s 转为 %s" , i , i + 1 , str[i] + "" + str[i + 1] , exchangeChar1));
int n_2_num = processSubStr(str , i + 2 , list2);
return n_1_num + n_2_num;
}
return n_1_num;
}else if(str[i] == '2'){
//如果 i位置是2 有两种情况 i位置的数字单独转为一个字母 如果 1=<i+1位置<=6 i和i+1合起来转为一个字母
List list1 = new ArrayList();
list1.addAll(list);
char exchangeChar = exchangeChar(Integer.parseInt(String.valueOf(str[i])));
list1.add(exchangeChar);
System.out.println(String.format("第 %s 位置的 %s 转为 %s" , i , str[i] , exchangeChar));
int n_1_num = processSubStr(str , i + 1 , list1);
if(i + 1 < str.length && str[i+1] >= '1' && str[i+1] <= '6'){
List list2 = new ArrayList();
list2.addAll(list);
char exchangeChar1 = exchangeChar(Integer.parseInt(String.valueOf(str[i] + "" + str[i + 1])));
list2.add(exchangeChar1);
System.out.println(String.format("第 %s%S 位置的 %s 转为 %s" , i , i + 1 , str[i] + "" + str[i + 1] , exchangeChar1));
int n_2_num = processSubStr(str , i + 2 , list2);
return n_1_num + n_2_num;
}
}
List list1 = new ArrayList();
list1.addAll(list);
char exchangeChar = exchangeChar(Integer.parseInt(String.valueOf(str[i])));
list1.add(exchangeChar);
System.out.println(String.format("第 %s 位置的 %s 转为 %s" , i , str[i] , exchangeChar));
// 3-9 只有一种情况 就是把i位置的数字转为字母 不可以把 i和i+1的字母合起来一起转
return processSubStr(str , i + 1 , list1);
}
public char exchangeChar(int num){
switch (num){
case 1 : return 'A';
case 2 : return 'B';
case 3 : return 'C';
case 4 : return 'D';
case 5 : return 'E';
case 6 : return 'F';
case 7 : return 'G';
case 8 : return 'H';
case 9 : return 'I';
case 10 : return 'J';
case 11 : return 'K';
case 12 : return 'L';
case 13 : return 'M';
case 14 : return 'N';
case 15 : return 'O';
case 16 : return 'P';
case 17 : return 'Q';
case 18 : return 'R';
case 19 : return 'S';
case 20 : return 'T';
case 21 : return 'U';
case 22 : return 'V';
case 23 : return 'W';
case 24 : return 'S';
case 25 : return 'Y';
case 26 : return 'Z';
default: return '0';
}
}
public int number(String str){
if(str==null||str.length()==0){
return 0;
}
return process(str.toCharArray(),0);
}
//i之前的位置,如何转化已经做过决定
//i...有多少种转化结果
public int process(char[] str,int i){
if(i==str.length){
return 1;//把之前做的所有选择的这种结果返回
}
if(str[i]=='0'){
return 0;//0字符代表之前做的选择有错误 0不代表任何字母且不能以0开头
}
//数字1肯定可以和后面的一位数字作为整体 数字2要分情况谈论
if(str[i]=='1'){
int res=process(str,i+1);//i作为单独的部分,后续有多少种方式
if(i+1<str.length){//注意这里的条件判断
res+=process(str,i+2);//i和i+1作为单独的部分,后续有多少种方式
}
return res;
}
if(str[i]=='2'){
int res=process(str,i+1);
//i和i+1作为单独的部分并且没有超过26,后续有多少种方法
if(i+1<str.length&&(str[i+1]>='0'&&str[i+1]<='6')){
res+=process(str,i+2);
}
return res;
}
//这里有潜台词 3-9的数字只可能做单独选择
return process(str,i+1);
}
}
打印结果如下
12
第 0 位置的 1 转为 A
第 1 位置的 2 转为 B
第 2 位置的 3 转为 C
第 3 位置的 4 转为 D
第 4 位置的 5 转为 E
第 5 位置的 6 转为 F
第 6 位置的 1 转为 A
第 7 位置的 4 转为 D
第 8 位置的 2 转为 B
第 9 位置的 3 转为 C
第 10 位置的 1 转为 A
[A, B, C, D, E, F, A, D, B, C, A]
第 89 位置的 23 转为 W
第 10 位置的 1 转为 A
[A, B, C, D, E, F, A, D, W, A]
第 67 位置的 14 转为 N
第 8 位置的 2 转为 B
第 9 位置的 3 转为 C
第 10 位置的 1 转为 A
[A, B, C, D, E, F, N, B, C, A]
第 89 位置的 23 转为 W
第 10 位置的 1 转为 A
[A, B, C, D, E, F, N, W, A]
第 12 位置的 23 转为 W
第 3 位置的 4 转为 D
第 4 位置的 5 转为 E
第 5 位置的 6 转为 F
第 6 位置的 1 转为 A
第 7 位置的 4 转为 D
第 8 位置的 2 转为 B
第 9 位置的 3 转为 C
第 10 位置的 1 转为 A
[A, W, D, E, F, A, D, B, C, A]
第 89 位置的 23 转为 W
第 10 位置的 1 转为 A
[A, W, D, E, F, A, D, W, A]
第 67 位置的 14 转为 N
第 8 位置的 2 转为 B
第 9 位置的 3 转为 C
第 10 位置的 1 转为 A
[A, W, D, E, F, N, B, C, A]
第 89 位置的 23 转为 W
第 10 位置的 1 转为 A
[A, W, D, E, F, N, W, A]
第 01 位置的 12 转为 L
第 2 位置的 3 转为 C
第 3 位置的 4 转为 D
第 4 位置的 5 转为 E
第 5 位置的 6 转为 F
第 6 位置的 1 转为 A
第 7 位置的 4 转为 D
第 8 位置的 2 转为 B
第 9 位置的 3 转为 C
第 10 位置的 1 转为 A
[L, C, D, E, F, A, D, B, C, A]
第 89 位置的 23 转为 W
第 10 位置的 1 转为 A
[L, C, D, E, F, A, D, W, A]
第 67 位置的 14 转为 N
第 8 位置的 2 转为 B
第 9 位置的 3 转为 C
第 10 位置的 1 转为 A
[L, C, D, E, F, N, B, C, A]
第 89 位置的 23 转为 W
第 10 位置的 1 转为 A
[L, C, D, E, F, N, W, A]
12