✅创作者:陈书予
🎉个人主页:陈书予的个人主页
🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区
🌟专栏地址: Java华为OD机试真题(2022&2023)
文章目录
- 1. 题目描述
- 2. 输入描述
- 3. 输出描述
- 4. Java算法源码
- 5. 测试
- 6.解题思路
1. 题目描述
每个数字对应多个字母,对应关系如下:
0:a,b,c 1:d,e,f 2:g,h,i 3:j,k,l 4:m,n,o 5:p,q,r 6:s,t 7:u,v 8:w,x 9:y, z
输入一串数字后,通过数字和字母的对应关系可以得到多个字母字符串(要求按照数字的顺序组合字母字符串);
屏蔽字符: 屏蔽字符中的所有字母不能同时在输出的字符串出现,如屏蔽字符时abc,则要求字符串中不能同时出现a,b,c,但是允许同时出现a,b;a,c;b,c等;
给定一个数字字符串和一个屏蔽字符串,输出所有可能的字符组合;
例如:
输入数字字符串78和屏蔽字符串ux,输出结果为uw,vw,vx;
数字字符串78,可以得到如下字符串: uw,ux,vw,vx;由于ux是屏蔽字符串,因此排除ux,最终的输出时uw,vw,vx;
2. 输入描述
- 第一行输入为一串数字字符串,数字字符串中的数字不允许重复,数字字符串的长度大于0,小于等于5;
- 第二行输入是屏蔽字符,屏蔽字符的长度一定小于数字字符串的长度,屏蔽字符串中字符不会重复。
3. 输出描述
输出可能的字符串组合。
注:字符串之间使用逗号隔开,最后一个字符串后携带逗号
4. Java算法源码
/**
* 78
* ux
*/
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// 数字字符串
String numbers = in.nextLine();
// 屏蔽字符串
String noStr = in.nextLine();
List<String> list = new ArrayList<String>();
// 数字对应的字母组合
String[] arr = new String[numbers.length()];
for (int i = 0; i < numbers.length(); i++) {
// 单个数字
int number = Integer.valueOf(numbers.charAt(i)+"");
// 数字对应的字母组合
arr[i] = hashMap.get(number);
}
int index = 0;
LinkedList<Character> charLine = new LinkedList<>();
solution(arr, index, list, charLine, noStr);
for (int i = 0; i < list.size(); i++) {
System.out.print(list.get(i) + ",");
}
}
/**
*
* @param arr 数字对应的字母组合
* @param index 第几个字母
* @param list 不包含屏蔽字符串的字符串集合
* @param charLine 合格的字母集合
* @param noStr 屏蔽字符串
*/
public static void solution(String[] arr, int index, List<String> list, LinkedList<Character> charLine, String noStr) {
if (index == arr.length) {
StringBuilder builder = new StringBuilder();
for (Character c : charLine) {
builder.append(c);
}
// 屏蔽字符中的所有字母不能同时在输出的字符串出现
if (isContainsNoStr(builder.toString(), noStr)) {
list.add(builder.toString());
}
return;
}
for (int i = 0; i < arr[index].length(); i++) {
charLine.addLast(arr[index].charAt(i));
solution(arr, index + 1, list, charLine, noStr);
charLine.removeLast();
}
}
/**
* 是否包含屏蔽字符串
*
* 屏蔽字符中的所有字母不能同时在输出的字符串出现
*/
public static boolean isContainsNoStr(String s, String noStr) {
boolean flag = false;
// 要求按照数字的顺序组合字母字符串
for (int i = 0; i < noStr.length(); i++) {
if (!s.contains(noStr.charAt(i) + "")) {
flag = true;
break;
}
}
return flag;
}
/**
* 每个数字对应多个字母
*/
private static Map<Integer, String> hashMap = new HashMap<Integer, String>();
static {
hashMap.put(0, "abc");
hashMap.put(1, "def");
hashMap.put(2, "ghi");
hashMap.put(3, "jkl");
hashMap.put(4, "mno");
hashMap.put(5, "pqr");
hashMap.put(6, "st");
hashMap.put(7, "uv");
hashMap.put(8, "wx");
hashMap.put(9, "yz");
}
5. 测试
6.解题思路
- 读取输入的数字字符串
numbers
。 - 读取输入的屏蔽字符串
noStr
。 - 创建一个空的字符串列表
list
用于存储不包含屏蔽字符串的字符串组合。 - 创建一个字符串数组
arr
,长度为numbers
的长度,用于存储数字对应的字母组合。 - 遍历
numbers
中的每个数字,将对应的字母组合存入arr
数组。 - 初始化索引
index
为 0,创建一个空的字符链表charLine
,用于存储合格的字母集合。 - 调用
solution
方法,传入arr
数组、index
、list
、charLine
、noStr
进行递归处理。 - 在
solution
方法中,如果index
等于arr
的长度,表示已经遍历完所有数字对应的字母组合,将charLine
中的字母按顺序组成字符串builder
。 - 调用
isContainsNoStr
方法,判断builder
是否包含屏蔽字符串noStr
。 - 如果不包含,则将
builder
添加到list
中。 - 否则,返回上一层递归。
- 在
solution
方法中,遍历当前数字对应的字母组合的每个字母,将字母添加到charLine
中,并递归调用solution
方法,将index
值加1。 - 递归完成后,将最后一个添加的字母从
charLine
中移除,回溯到上一层递归。 - 输出
list
列表中的所有字符串,使用逗号分隔。