(200分)- 九宫格按键输入(Java & JS & Python)
·
(200分)- 九宫格按键输入(Java & JS & Python)
题目描述
九宫格按键输入,输出显示内容,有英文和数字两个模式,默认是数字模式,数字模式直接输出数字,英文模式连续按同一个按键会依次出现这个按键上的字母,如果输入”/”或者其他字符,则循环中断。
字符对应关系如图:

要求输入一串按键,输出屏幕显示。
输入描述
输入范围为数字 0~9 和字符’#’、’/’,输出屏幕显示,例如,
在数字模式下,输入 1234,显示 1234
在英文模式下,输入 1234,显示,adg
输出描述
#用于切换模式,默认是数字模式,执行#后切换为英文模式;
/表示延迟,例如在英文模式下,输入 22/222,显示为 bc;
英文模式下,多次按同一键,例如输入 22222,显示为 b;
用例
| 输入 | 123#222235/56 |
| 输出 | 123adjjm |
题目解析
本题考察逻辑分析能力和栈结构的应用。
解题思路如下:
-
初始化:
- 定义栈stack存储结果
- 设置isEng标志记录当前模式(false为数字模式,true为英文模式),初始为false
-
遍历字符串s的每个字符c:
- 遇到'#':切换模式前需检查:
- 若当前为英文模式,需先处理栈顶数字的转换
- 然后切换模式:isEng = !isEng
- 遇到'/':处理循环中断
- 仅当英文模式时才需处理栈顶数字转换
- 其他字符:
- 数字模式:直接入栈
- 英文模式:
- 栈顶字符与c不同:需中断循环(转换栈顶数字)
- 相同:增加栈顶数字的重复计数
- 遇到'#':切换模式前需检查:
-
循环中断逻辑的注意事项:
- 必须处于英文模式
- 栈不能为空
Java算法源码
import java.util.LinkedList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(getResult(sc.nextLine()));
}
static String[] dict = {" ", ",.", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
static LinkedList<Character> stack = new LinkedList<>();
static int topRepeat = 0;
static boolean isEng = false;
public static String getResult(String s) {
s += " ";
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '#':
// 如果输入”/”或者其他字符,则循环中断
interrupt();
// #用于切换模式
isEng = !isEng;
break;
case '/':
// 如果输入”/”或者其他字符,则循环中断
interrupt();
break;
default:
// 数字模式
// 直接输出数字
if (!isEng) {
stack.add(c);
break;
}
// 英文模式,需要检查栈顶
// 如果栈顶不是英文模式字符(这里可以基于topRepeat判断,topRepeat是英文模式下对应按键的重复次数,如果为0,则说明栈顶存储的不是英文模式字符),则缓存对应字符c,并记录重复次数
if (topRepeat == 0) {
stack.add(c);
topRepeat++;
break;
}
// 如果栈顶字符有重复次数,则此时需要比较当前按键c和之前重复的按键stack.getLast是否相同
if (c != stack.getLast()) {
// 如果输入”/”或者其他字符,则循环中断
interrupt();
stack.add(c);
}
topRepeat++;
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < stack.size() - 1; i++) sb.append(stack.get(i));
return sb.toString();
}
// 英文模式连续按同一个按键会依次出现这个按键上的字母,如果输入”/”或者其他字符,则循环中断
// interrupt用于处理循环中断后的逻辑
public static void interrupt() {
if (!isEng || stack.size() == 0 || topRepeat == 0) return;
stack.add(map(stack.removeLast(), topRepeat));
topRepeat = 0;
}
// 基于dict,获取一个数字c被重复repeat次后,对应的字符
public static char map(char c, int repeat) {
int num = Integer.parseInt(c + "");
String s = dict[num];
int i = (repeat - 1) % s.length();
return s.charAt(i);
}
}
JS算法源码
/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const stack = [];
let topRepeat = 0;
let isEng = false;
rl.on("line", (line) => {
console.log(getResult(line));
// 如果需要测试多组用例,这里需要将全局变量重置
stack.length = 0;
topRepeat = 0;
isEng = false;
});
function getResult(s) {
s += " ";
for (let c of s) {
switch (c) {
case "#":
// 如果输入”/”或者其他字符,则循环中断
interrupt();
// #用于切换模式
isEng = !isEng;
break;
case "/":
// 如果输入”/”或者其他字符,则循环中断
interrupt();
break;
default:
// 数字模式直接输出数字
if (!isEng) {
stack.push(c);
break;
}
// 英文模式,需要检查栈顶
// 如果栈顶不是英文模式字符(这里可以基于topRepeat判断,topRepeat是英文模式下对应按键的重复次数,如果为0,则说明栈顶存储的不是英文模式字符),则缓存对应字符c,并记录重复次数
if (topRepeat == 0) {
stack.push(c);
topRepeat++;
break;
}
// 如果栈顶字符有重复次数,则此时需要比较当前按键c和之前重复的按键stack.getLast是否相同
if (c != stack.at(-1)) {
// 如果输入”/”或者其他字符,则循环中断
interrupt();
stack.push(c);
}
topRepeat++;
}
}
return stack.slice(0, stack.length - 1).join("");
}
// 英文模式连续按同一个按键会依次出现这个按键上的字母,如果输入”/”或者其他字符,则循环中断
// interrupt用于处理循环中断后的逻辑
function interrupt() {
if (!isEng || stack.length == 0 || topRepeat == 0) return;
stack.push(map(stack.pop(), topRepeat));
topRepeat = 0;
}
const dict = [
" ",
",.",
"abc",
"def",
"ghi",
"jkl",
"mno",
"pqrs",
"tuv",
"wxyz",
];
// 基于dict,获取一个数字c被重复repeat次后,对应的字符
function map(c, repeat) {
const num = parseInt(c);
const s = dict[num];
const i = (repeat - 1) % s.length;
return s[i];
}
Python算法源码
# 输入获取
s = input()
# 全局变量
stack = []
topRepeat = 0
isEng = False
dictionary = (" ", ",.", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz")
# 基于dictionary,获取一个数字c被重复repeat次后,对应的字符
def mapping(c, repeat):
num = int(c)
s1 = dictionary[num]
i = (repeat - 1) % len(s1)
return s1[i]
# 英文模式连续按同一个按键会依次出现这个按键上的字母,如果输入”/”或者其他字符,则循环中断
# interrupt用于处理循环中断后的逻辑
def interrupt():
global topRepeat
if not isEng or len(stack) == 0 or topRepeat == 0:
return
stack.append(mapping(stack.pop(), topRepeat))
topRepeat = 0
# 算法入口
def getResult():
global s
global isEng
global topRepeat
s += " "
for c in s:
if c == '#':
# 如果输入”/”或者其他字符,则循环中断
interrupt()
# #用于切换模式
isEng = not isEng
elif c == '/':
# 如果输入”/”或者其他字符,则循环中断
interrupt()
else:
# 数字模式直接输出数字
if not isEng:
stack.append(c)
continue
# 英文模式,需要检查栈顶
# 如果栈顶不是英文模式字符(这里可以基于topRepeat判断,topRepeat是英文模式下对应按键的重复次数,如果为0,则说明栈顶存储的不是英文模式字符),则缓存对应字符c,并记录重复次数
if topRepeat == 0:
stack.append(c)
topRepeat += 1
continue
# 如果栈顶字符有重复次数,则此时需要比较当前按键c和之前重复的按键stack.getLast是否相同
if c != stack[-1]:
# 如果输入”/”或者其他字符,则循环中断
interrupt()
stack.append(c)
topRepeat += 1
return "".join(stack[:-1])
# 算法调用
print(getResult())更多推荐



所有评论(0)