简易二进制编辑器

题目:简易二进制编辑器

请实现一个简易的二进制文本编辑器。编辑器处理的数字必须是"合法的二进制数字",并且支持一系列操作来修改内容和移动光标。

规则定义

  1. 合法二进制数字:

    • 不能有前导零。

    • 前导零定义:

      • 从左到右,第一个非 '0' 数字之前的所有 '0'。
      • 对于一个全由 '0' 组成的数字,最后一个 '0' 之前的所有 '0'。
    • 合法示例: 1101, 0, 1, 100

    • 非法示例: 00, 01

  2. 初始状态:

    • 编辑器内容为一个给定的二进制数字字符串 inputStr(可能为空)。
    • 光标默认在字符串的最右侧

功能要求 (操作指令)

  • 0 :在光标位置插入一个数字 '0'

    • 光标停留在新插入数字的右侧。
    • 注意: 如果本次插入会导致数字变为非法的"前导零"格式,则不做任何处理
  • 1 :在光标位置插入一个数字 '1'

    • 光标停留在新插入数字的右侧。
    • 注意: 如果插入后导致出现前导零(例如,在 "0" 前面插入 "1" 变成 "10" 是合法的,但在 "0" 后面插入 "1" 变成 "01" 是非法的),需要将非法的前导零删除。
  • B (退格 Backspace):删除光标位置左侧相邻的一个数字。

    • 光标位置相应左移一位。
    • 如果删除后导致出现前导零(例如,从 "101" 中删除 '1' 变成 "01"),需要将前导零删除,并且光标需要移动到最左侧
    • 如果光标已在最左侧(行首),则不做任何处理。
  • L (左移 Left):光标向左移动一个位置。

    • 如果光标已在最左侧,则不做任何处理。
  • R (右移 Right):光标向右移动一个位置。

    • 如果光标已在最右侧,则不做任何处理。

任务

现给出初始二进制数字字符串 inputStr,以及一系列操作 cmds,请依次进行编辑操作,最后返回编辑器内最终的二进制数字字符串。


解答要求

  • 时间限制: 1000ms
  • 内存限制: 256MB

输入

  • 第一个参数 inputStr:

    • 一个由 '0' 或 '1' 组成的二进制数字字符串,或空串 ""
    • 0 <= inputStr.length <= 1000
    • 用例保证初始 inputStr 不含前导零。
  • 第二个参数 cmds:

    • 一个表示系列操作的字符串。
    • 1 <= cmds.length <= 1000
    • cmds 中的字符仅为 0, 1, B, L, R 之一。

输出

  • 一个二进制数字字符串,可能为空字符串 ""

样例

输入样例 1

arduino 复制代码
"10"
"0LLB0R1"

输出样例 1

arduino 复制代码
"1"

样例 1 解释

操作 字符串状态 (x 表示光标) 解释
初始 10x 初始为 "10",光标在最右侧。
0 100x 在末尾插入 '0'。
L 10x0 光标左移,在两个 '0' 之间。
L 1x00 光标再次左移,在 '1' 和 '0' 之间。
B x0 退格删除 '1'。剩下 "00",这有前导零,需规范化为 "0",且光标移到最左侧。
0 x0 尝试在最左侧插入 '0'。因为当前字符串是 "0",插入会导致 "00",非法,所以不处理。
R 0x 光标右移。
1 1x 在末尾插入 '1',得到 "01"。这有前导零,需规范化为 "1"。光标也相应调整。
最终 1x 最终结果为 "1"。
java 复制代码
import java.util.Scanner;

/**
封装简易二进制编辑器状态和逻辑的类
*/
class BinaryEditor {
    // 使用 StringBuilder 作为文本缓冲区,因为它对于频繁的插入和删除操作效率很高
    private StringBuilder buffer;
    // 记录光标位置,范围从 0 到 buffer.length()
    private int cursorPos;

    /**
     * 构造函数,用初始字符串初始化编辑器
     */
    public BinaryEditor(String initialStr) {
        // 假设初始字符串是合法的
        this.buffer = new StringBuilder(initialStr);
        // 光标默认在最后一个数字的右侧
        this.cursorPos = initialStr.length();
    }

    /**
     * 循环处理所有命令
     * @param cmds 包含所有操作的命令字符串
     */
    public void processCommands(String cmds) {
        for (char cmd : cmds.toCharArray()) {
            switch (cmd) {
                case '0': insertZero(); break;
                case '1': insertOne(); break;
                case 'B': backspace(); break;
                case 'L': moveLeft(); break;
                case 'R': moveRight(); break;
            }
        }
    }

    /**
     * 获取编辑器最终的文本内容
     */
    public String getText() {
        return this.buffer.toString();
    }

    // --- 各个操作的具体实现 ---
    private void insertZero() {
        // 规则:如果插入 '0' 会导致非法的前导零,则不做任何处理。重点。
        // 非法情况1: 字符串非空,且在最左侧插入 '0' (例如 "101" -> "0101")
        // 非法情况2: 字符串本身是 "0",再插入一个 '0' 会变成 "00"
        boolean isIllegal = (cursorPos == 0 && buffer.length() > 0) || buffer.toString().equals("0");

        if (!isIllegal) {
            buffer.insert(cursorPos, '0');
            cursorPos++; // 光标右移
        }
    }

    private void insertOne() {
        // 直接插入 '1'
        buffer.insert(cursorPos, '1');
        cursorPos++; // 光标右移
        // 重点:插入 '1' 后可能会产生需要移除的前导 '0' (例如 "0" -> "01")
        normalize();
    }

    private void backspace() {
        // 如果光标已在最左侧,不做任何处理
        if (cursorPos == 0) {
            return;
        }

        // 光标左移一位并删除该位置的字符
        cursorPos--;
        buffer.deleteCharAt(cursorPos);

        // 重点:删除后可能产生前导零 (例如 "101" -> "01"),需要规范化
        // 如果规范化操作确实删除了字符,则光标移动到最左侧
        if (normalize()) {
            cursorPos = 0;
        }
    }

    private void moveLeft() {
        if (cursorPos > 0) {
            cursorPos--;
        }
    }

    private void moveRight() {
        if (cursorPos < buffer.length()) {
            cursorPos++;
        }
    }

    /**
     * 规范化函数:移除所有非法的前导零。
     * @return 如果实际执行了删除操作,返回 true;否则返回 false。
     */
    private boolean normalize() {
        boolean removed = false;
        // 只要字符串长度大于1且以 '0' 开头,就移除 '0'
        while (buffer.length() > 1 && buffer.charAt(0) == '0') {
            buffer.deleteCharAt(0);
            // 因为光标左边的字符被删除了,光标的绝对位置需要左移
            cursorPos--;
            removed = true;
        }
        // 防止光标位置变为负数(理论上不会,因为 normalize 前会插入 '1' 或删除后仍有字符)
        cursorPos = Math.max(0, cursorPos);
        return removed;
    }
}


public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 读取初始字符串
        String inputStr = scanner.nextLine();
        // 读取命令字符串
        String cmds = scanner.nextLine();
        scanner.close();

        // 创建编辑器实例
        BinaryEditor editor = new BinaryEditor(inputStr);

        // 处理所有命令
        editor.processCommands(cmds);

        // 输出最终结果
        System.out.println(editor.getText());
    }
}
相关推荐
zhanghe68720 分钟前
es的密码带有特殊字符,导出
java
指掀涛澜天下惊27 分钟前
强化学习进阶篇八 策略梯度算法
深度学习·学习·算法·强化学习
pnoker32 分钟前
IoT DC3 概念解读:把设备抽象成一套语义模板——位号、指令、事件与面向智能体的设备建模
java·人工智能·物联网·iot·dc3
乌萨奇也要立志学C++32 分钟前
【洛谷】kmp算法
开发语言·算法
my_realmy33 分钟前
Java SE 基础学习笔记(一):面向对象、继承多态、抽象接口与异常(JDK 8)
java·多线程·并发··生产者消费者模式
禹凕40 分钟前
Dijkstra算法详解与应用
python·算法
天远数科1 小时前
风险治理实战:基于天远车信盟出险构建自动化理赔核保流水线
java·网络·人工智能·自动化
YaraMemo2 小时前
元启发式算法框架
人工智能·算法·5g·信息与通信·启发式算法·信号处理
骇客野人2 小时前
SpringBoot电商系统用户注册、登录、留存及数据埋点设计与落地实施方案
java·spring boot·后端
qiuhaipeng12 小时前
Claude code 升级后上下文长度变短问题
java·前端·数据库