(C卷,200分)- 九宫格按键输入(Java & JS & Python)

题目描述

九宫格按键输入,输出显示内容,有英文和数字两个模式,默认是数字模式,数字模式直接输出数字,英文模式连续按同一个按键会依次出现这个按键上的字母,如果输入”/”或者其他字符,则循环中断。

字符对应关系如图:

要求输入一串按键,输出屏幕显示。

输入描述

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

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

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

输出描述

#用于切换模式,默认是数字模式,执行#后切换为英文模式;

/表示延迟,例如在英文模式下,输入 22/222,显示为 bc;

英文模式下,多次按同一键,例如输入 22222,显示为 b;

用例

输入 123#222235/56
输出 123adjjm

题目解析

本题主要考察逻辑分析,和栈结构使用。

我的解题思路如下:

首先,定义一个栈stack,用于缓存结果。再定义一个isEng标识来记录当前模式,true代表英文模式,false代表数字模式。isEng初始化为false。

然后,遍历输入的字符串s,将s的每一个字符c遍历出来:

  • 如果 c == '#',则表示要切换模式,即让 isEng = !isEng,但是在切换模式之前,需要先检查isEng是否为英文模式,如果是英文模式,则切换前,需要先将栈顶数字的循环中断,并转化为对应的字母。
  • 如果 c == '/',则表示要循环中断,此时先检查isEng是否为英文模式,若是,则再将栈顶数字转化为对应字母,若不是,则不做处理
  • 如果 c 为其他字符,则:
  1. 如果isEng为数字模式,则c直接压入stack中
  2. 如果isEng为英文模式,则需要检查stack栈顶元素是否和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())

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?