当前位置: 首页 > article >正文

【华为OD-E卷 - 九宫格按键输入 100分(python、java、c++、js、c)】

【华为OD-E卷 - 九宫格按键输入 100分(python、java、c++、js、c)】

题目

九宫格按键输入,有英文和数字两个模式,默认是数字模式,数字模式直接输出数字,英文模式连续按同一个按键会依次出现这个按键上的字母,如果输入 “/” 或者其他字符,则循环中断,输出此时停留的字母。
数字和字母的对应关系如下,注意 0 只对应空格

输入描述

  • 输入范围为数字 0~9 和字符’#’、’/’,输出屏幕显示,例如:

在数字模式下,输入 1234,显示 1234 在英文模式下,输入 1234,显示,adg

输出描述

  • 输出屏幕显示的字符

用例

用例一:
输入:
2222/22
输出:
222222
用例二:
输入:
#2222/22
输出:
ab
用例三:
输入:
#222233
输出:
ae

python解法

  • 解题思路:
  • 这段代码的目标是模拟手机键盘的输入处理,特别是传统的T9输入法。具体来说,用户输入一串字符,程序根据输入的字符来模拟手机键盘的按键输入,最终输出对应的文本。

T9输入法:T9输入法使用数字键来输入字母。例如,按键 2 映射到字母 “abc”,按键 3 映射到字母 “def”,依此类推。如果连续按多次同一个数字键,则输出字母的不同选择。例如,按键 “2” 第一次按下输出 “a”,第二次输出 “b”,第三次输出 “c”。

输入规则:

输入是一个字符串,字符可以是字母、空格、数字、特殊字符(如 “#”, “/”, 等)。
特殊字符 # 切换输入模式:如果当前输入是英文模式,则切换为数字输入模式,反之亦然。
切换模式时,缓存区的字符会被清空,并根据输入模式来处理后续字符。
/ 则是用于清空当前缓存区的字符,不做任何字符转换。
字符 char 根据当前模式和按键次数,决定最终字符的输出

class PhoneInput:
    # 模拟手机键盘上每个按键对应的字母
    KEYS = (" ", ",.", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz")

    def __init__(self):
        # 初始化缓冲区、语言模式、重复计数器
        self.buf = []  # 用来缓存输入的字符
        self.is_eng = False  # 是否处于英文模式
        self.rep = 0  # 记录同一按键连续按下的次数

    def process(self, text):
        """
        处理输入的字符。遍历每个字符,处理后返回最终的文本结果。
        """
        for char in text + ' ':
            # 如果遇到 "#",切换语言模式并清空当前输入
            if char == '#':
                self._flush()  # 清空当前缓存的字符
                self.is_eng = not self.is_eng  # 切换英文与数字模式
            # 如果遇到 "/",清空当前缓存区
            elif char == '/':
                self._flush()  # 清空当前缓存
            else:
                self._handle_char(char)  # 处理当前字符
        return ''.join(self.buf)  # 返回最终的字符结果,缓存区内容合并成字符串

    def _handle_char(self, char):
        """
        根据当前模式(英文或数字)处理当前输入的字符。
        """
        # 如果是数字模式,直接将字符加入缓冲区
        if not self.is_eng:
            self.buf.append(char)
        # 如果是英文模式且当前字符与缓存区的最后一个字符不同
        elif self.rep == 0 or char != self.buf[-1]:
            self._flush()  # 清空缓存,准备新输入
            self.buf.append(char)  # 将当前字符加入缓存
            self.rep = 1  # 重置重复计数器
        else:
            # 如果当前字符与最后一个字符相同,重复计数器加1
            self.rep += 1

    def _flush(self):
        """
        刷新缓存区,根据输入模式决定当前按键的输出字符。
        """
        if self.is_eng and self.rep > 0:
            # 如果是英文模式,并且有重复按键的记录
            key = int(self.buf.pop())  # 获取按键的数字(最后一个字符)
            # 根据重复的次数决定字符的选择,使用取余操作循环选择字母
            char = self.KEYS[key][(self.rep - 1) % len(self.KEYS[key])]
            self.buf.append(char)  # 将最终选择的字母加入缓存区
        self.rep = 0  # 重置重复计数器

def main():
    processor = PhoneInput()  # 创建处理器对象
    result = processor.process(input())  # 获取输入并处理
    print(result)  # 输出处理后的结果

if __name__ == "__main__":
    main()  # 调用main函数,启动程序

java解法

  • 解题思路
  • 本题的目标是模拟手机键盘的输入处理,类似于传统的T9输入法。每个数字键对应多个字符,连续按同一个数字键时会依次选择对应的字符。用户输入的字符经过处理后,程序返回最终的文本。

输入模式切换:如果遇到 # 字符,输入模式会在“英文模式”和“数字模式”之间切换。
缓存与重复按键处理:如果当前是英文模式且用户连续按下同一个数字键,程序会根据按键的次数输出对应的字符;如果是数字模式,按键直接转换为数字。
处理流程:
输入字符串:逐字符处理输入的字符串。
输入模式切换:
如果是 #,切换输入模式,并清空缓存。
如果是 /,清空当前缓存。
字符处理:根据当前模式处理字符:
如果是“数字模式”,直接将字符追加到输出中。
如果是“英文模式”,则根据字符的重复按下次数,决定输出字符(比如按 2 一次是 “a”,按两次是 “b”)。
清空操作:flush() 方法在需要时将缓存的字符转换为最终的输出字符。

import java.util.Scanner;

public class Main {
    // 手机键盘的每个数字键对应的字母映射
    private static final String[] KEYS = {" ", ",.", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    
    private StringBuilder buf;  // 用来存储当前的字符序列
    private boolean isEng;      // 是否处于英文模式
    private int rep;            // 记录当前字符的重复按下次数

    // 构造方法,初始化变量
    public Main() {
        this.buf = new StringBuilder();  // 初始化缓存区
        this.isEng = false;  // 默认处于数字模式
        this.rep = 0;         // 重复计数初始化为0
    }

    // 处理输入文本的核心方法
    public String process(String text) {
        // 将输入的文本加上一个空格处理末尾
        for (char ch : (text + " ").toCharArray()) {
            if (ch == '#') {
                flush();  // 如果遇到#,切换模式并清空缓存
                isEng = !isEng;  // 切换英文模式与数字模式
            } else if (ch == '/') {
                flush();  // 如果遇到/,清空缓存
            } else {
                handleChar(ch);  // 处理其他字符
            }
        }
        return buf.toString();  // 返回处理后的结果
    }

    // 处理输入字符的逻辑
    private void handleChar(char ch) {
        // 如果是数字模式,直接将字符加入缓存
        if (!isEng) {
            buf.append(ch);
        } else if (rep == 0 || ch != buf.charAt(buf.length() - 1)) {
            // 如果是英文模式且当前字符与缓存的最后一个字符不同,则清空缓存,重新开始
            flush();
            buf.append(ch);  // 将当前字符添加到缓存
            rep = 1;  // 重置重复计数为1
        } else {
            // 如果当前字符与最后一个字符相同,增加重复计数
            rep++;
        }
    }

    // 刷新缓存的方法,根据当前输入决定最终字符
    private void flush() {
        // 只有在英文模式下且有重复计数时,才进行处理
        if (isEng && rep > 0) {
            // 获取当前字符对应的数字键
            int key = Character.getNumericValue(buf.charAt(buf.length() - 1));
            // 根据重复次数选取对应的字符
            char newChar = KEYS[key].charAt((rep - 1) % KEYS[key].length());
            // 替换缓存中的字符
            buf.setCharAt(buf.length() - 1, newChar);
        }
        rep = 0;  // 重置重复计数
    }

    // 主函数,程序入口
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);  // 创建Scanner对象读取输入
        String input = scanner.nextLine();  // 读取用户输入的字符串
        scanner.close();  // 关闭Scanner

        Main processor = new Main();  // 创建Main对象,处理输入
        String result = processor.process(input);  // 处理输入
        System.out.println(result);  // 输出最终结果
    }
}

C++解法

  • 解题思路
更新中

C解法

  • 解题思路

更新中

JS解法

  • 解题思路

  • 这段代码的目标是模拟一个手机键盘的输入处理,类似于传统的T9输入法,其中用户输入的数字键对应多个字母,连续按同一数字键可以依次选择不同的字母。当遇到特殊字符时(例如 # 和 /),程序会根据这些输入切换输入模式或清空当前输入。

输入模式切换:通过 # 来切换输入模式,英文模式和数字模式之间进行切换。英文模式下,连续按同一个数字键可以输出不同的字母;数字模式下,直接输出数字字符。
重复按键处理:在英文模式下,如果连续按下同一个数字键,程序会根据按下的次数来输出不同的字符。例如,按下数字 2 第一次输出 “a”,第二次输出 “b”,第三次输出 “c” 等。
清空操作:通过 / 来清空当前缓存的输入,并结束当前的重复按键计数。

// 引入 readline 模块,用于控制台输入输出
const readline = require("readline");

// 创建 readline 接口,允许从标准输入读取数据
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

// 定义状态变量
let isEng = false; // 是否处于英文模式,默认为 false,即数字模式
let repeatCount = 0; // 记录同一键的重复按次数
const stack = []; // 用于存储当前输入的字符序列

// 每当读取到一行输入时,触发此事件
rl.on("line", (line) => {
    console.log(getResult(line)); // 处理输入并打印结果

    // 全局变量重置
    isEng = false; // 重置为数字模式
    repeatCount = 0; // 重置重复计数
    stack.length = 0; // 清空栈
});

// 主处理函数,处理一行输入并返回最终结果
function getResult(s) {
    s += " "; // 在输入末尾加上空格,用于处理最后一个字符

    // 遍历输入的每个字符
    for (let c of s) {
        switch (c) {
            case "#":
                toggleMode(); // 遇到#,切换输入模式
                break;
            case "/":
                interrupt(); // 遇到/,清空当前输入
                break;
            default:
                handleCharacter(c); // 处理普通字符
                break;
        }
    }

    // 返回处理后的结果,去掉最后一个空格
    return stack.slice(0, stack.length - 1).join("");
}

// 切换输入模式的函数
function toggleMode() {
    interrupt(); // 切换模式前,先清空缓存
    isEng = !isEng; // 切换英文模式与数字模式
}

// 中断当前输入,清空缓存
function interrupt() {
    if (!isEng || stack.length === 0 || repeatCount === 0) return; // 如果不是英文模式,或者没有需要处理的字符,直接返回
    stack.push(mapChar(stack.pop(), repeatCount)); // 根据重复次数,更新当前字符
    repeatCount = 0; // 重置重复计数
}

// 处理普通字符
function handleCharacter(c) {
    if (!isEng) {
        // 如果是数字模式,直接将字符添加到栈中
        stack.push(c);
    } else {
        // 如果是英文模式,处理字符
        if (repeatCount === 0) {
            stack.push(c); // 如果是第一次按下该键,直接加入栈
            repeatCount++;  // 重复计数加1
        } else {
            // 如果当前字符与栈顶字符不同,则刷新当前输入
            if (c !== stack[stack.length - 1]) {
                interrupt(); // 清空当前缓存
                stack.push(c); // 加入新的字符
            }
            repeatCount++;  // 重复计数加1
        }
    }
}

// 定义数字键到字符的映射
const dict = [
    " ",    // 0 -> 空格
    ",.",   // 1 -> ",."
    "abc",  // 2 -> "abc"
    "def",  // 3 -> "def"
    "ghi",  // 4 -> "ghi"
    "jkl",  // 5 -> "jkl"
    "mno",  // 6 -> "mno"
    "pqrs", // 7 -> "pqrs"
    "tuv",  // 8 -> "tuv"
    "wxyz", // 9 -> "wxyz"
];

// 根据当前字符和重复次数,返回对应的字母
function mapChar(c, repeat) {
    const num = parseInt(c); // 获取数字键
    const chars = dict[num]; // 获取该数字键对应的字符映射
    return chars[(repeat - 1) % chars.length]; // 根据重复次数选择字符
}

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏


http://www.kler.cn/a/469132.html

相关文章:

  • 工控安全需求分析与安全保护工程
  • C++11——2:可变模板参数
  • Jetpack Compose 学习笔记(四)—— CompositionLocal 与主题
  • Go语言的 的并发编程(Concurrency)核心知识
  • 【服务器项目部署】✈️将本地项目部署到服务器(二)!
  • win32汇编环境,在窗口程序中画简单图形
  • Linux系统常用命令详解
  • 怎么找回电脑所有连接过的WiFi密码
  • 【论文阅读笔记】LTX-Video: Realtime Video Latent Diffusion
  • 如何让编码更加高效专注?——程序员编程选明基 RD280U显示器
  • Django Swagger文档库drf-spectacular
  • 【Rust 知识点杂记】
  • 微信小程序提示 miniprogram-recycle-view 引入失败
  • leetcode hot 100 最长递增子序列
  • 智能体语言 Shire 1.2 发布:自定义多文件编辑、Sketch 视图、流式 diff、智能上下文感知...
  • AI生成PPT,效率与创意的双重升级
  • 【开源免费】基于SpringBoot+Vue.JS精品在线试题库系统(JAVA毕业设计)
  • 开发小技巧分享 01:JSON解析工具
  • 入手51单片机的学习路径
  • Linux中的tcpdump抓包命令详解:抓取TCP和UDP数据包并按小时输出文件
  • 【MyBatis-Plus 进阶功能】开发中常用场景剖析
  • C++之STL
  • DeepSeek v3为何爆火?如何用其集成Milvus搭建RAG?
  • 数据库工程师进阶秘籍:云计算基础知识题目精选与答案(附PDF)
  • QT-------------对话框和多窗口程序设计
  • 《嵌入式系统:科技与艺术的交响曲》