华为OD机试 - 九宫格按键输入 - 逻辑分析(Java 2023 B卷 200分)
目录
- 专栏导读
- 一、题目描述
- 二、输入描述
- 三、输出描述
- 四、解题思路
- 五、Java算法源码
- 六、效果展示
- 1、输入
- 2、输出
- 3、说明
华为OD机试 2023B卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
九宫格按键输入,输出显示内容,有英文和数字两个模式,默认是数字模式,数字模式直接输出数字,英文模式连续按同一个按键会依次出现这个按键上的字母,如果输入" "或者其他字符,则循环中断。
字符对应关系如图:
二、输入描述
输入范围为数字0~9和字符#、/,输出屏幕显示,例如在数字模式下,输入1234,显示1234;在英文模式下,输入1234,显示,adg。
三、输出描述
#用于切换模式,默认是数字模式,执行#后切换为英文模式, /表示延迟,例如在英文模式下,输入22/222,显示为bc;
英文模式下,多次按同一键,例如输入22222,显示为b;
输入 | 输出 | 说明 |
---|---|---|
123#222235/56 | 123adjjm |
四、解题思路
- 输入一个字符串input;
- 定义digitalMode,true表示数字模式,false表示英文模式,默认true;
- 定义变量right,表示英文模式下,连续按键模式停止的坐标;
- 定义builder,拼接最后的输出内容;
- 遍历input;
- 如果输入" "或者其他字符,则循环中断;
- 如果是#,切换模式;
- 如果是/,表示延迟;
- 如果是数字模式,直接拼接;
- 如果是英文模式,获取下一个字符,判断与上一个字符是否相等;
- 如果下一个字符和当前字符相等,则进入连续按键模式;
- 如果下一个字符和当前字符相等,则表示连续模式结束,开始计算连续按键后输出的字母;
- 计算连续按键后输出的字母;
- 如果输入" "或者其他字符,则循环中断;
- 计算连续按键后输出的字母完毕,开始遍历后面的字符;
- 输出最后的拼接字符串builder。
五、Java算法源码
public class OdTest04 {
/**
* #用于切换模式,默认是数字模式,执行#后切换为英文模式, /表示延迟
* 如果输入" "或者其他字符,则循环中断。
* 123#222235/56 ---> 123adjjm
* 123#2222#3#5//5556 ---> 123a3jlm
* 123#2222#3#50//5556 ---> 123a3j
* 123#22022#3#5//5556 ---> 123b
*/
// 合法字符,如果输入" "或者其他字符,则循环中断
static String effectiveLetter = "123456789#/";
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
// true表示数字模式,false表示英文模式,默认true
boolean digitalMode = true;
// 英文模式下,连续按键模式停止的坐标
int right = -1;
// 最后的输出内容
StringBuilder builder = new StringBuilder();
for (int i = 0; i < input.length(); i++) {
// 123#222235/56 i = 4, 3对应8,此时right=7,,,下次遍历从8开始
if (right >= i) {
continue;
}
char ch = input.charAt(i);
// 如果输入" "或者其他字符,则循环中断
if (!effectiveLetter.contains(ch + "")) {
break;
}
switch (ch){
case '#': // 切换模式
digitalMode = !digitalMode;
break;
case '/': // /表示延迟
break;
default:
// 数字模式
if (digitalMode) {
builder.append(ch);
}else{ // 英文模式
int sameCount = 1;
boolean inputError = false;
for (int j = i + 1; j < input.length(); j++) {
// 下一个字符,判断与上一个字符是否相等
char next = input.charAt(j);
// 如果输入" "或者其他字符,则循环中断
if (!effectiveLetter.contains(next + "")) {
inputError = true;
break;
}
// 表示延迟
if (next == '/') {
right = j;
break;
}
// 如果下一个字符和当前字符相等,则进入连续按键模式
if (ch == next) {// 123#222235/56 i = 4, 3对应8,此时right=7,,,下次遍历从8开始
sameCount++;
right = j;
continue;
} else {// 如果下一个字符和当前字符相等,则表示连续模式结束,开始计算连续按键后输出的字母
break;
}
}
// 计算连续按键后输出的字母
char letter = getLetter(ch, sameCount);
builder.append(letter);
// 如果输入" "或者其他字符,则循环中断
if (inputError) {
break;
} else {// 计算连续按键后输出的字母完毕,开始遍历后面的字符
continue;
}
}
break;
}
}
// 最后的输出内容
System.out.println(builder);
}
/**
* 根据按键和连续的次数,获取对应的字母
*
* @param ch 按键
* @param sameCount 连续的次数
*/
static final String[] mapArr = {" ",",.?!","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
private static char getLetter(char ch, int sameCount) {
String letter = mapArr[Integer.parseInt(String.valueOf(ch))];
int index = (sameCount - 1) % letter.length();
return letter.charAt(index);
}
}
六、效果展示
1、输入
123#2222#3#5//5556
2、输出
123a3jlm
3、说明
- 遍历字符串123#2222#3#5//5556;
- #表示切换模式,/表示延迟;
- 123 --> 123;
- #切换到英文模式;
- 2222 --> a;
- #再次切换数字模式,3 --> 3;
- #再次切换英文模式,5 --> j;555 --> l;
- 6 --> m;
- 最后输出123a3jlm
🏆下一篇:华为OD机试 - 最长的顺子 - 感谢@禁止你发言提供的更简便算法(Java 2023 B卷 200分)
🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。