华为OD机试 - 仿LISP运算 - 逻辑分析(Java 2023 B卷 200分)

目录

华为OD机试 2023B卷题库疯狂收录中,刷题++点这里++

专栏导读

本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

LISP语言唯一的语法就是括号要配对,形如(OP P1 P2 ...),括号内元素由单个空格分割。其中第一个元素OP为操作符,后续元素均为其参数,参数个数取决于操作符类型。

注意:参数P1,P2也有可能是另外一个嵌套的(OP P1 P2...),当前OP类型为add/sub/mul/div(全小写) 分别代表整数的加减乘除法,简单起见,所有OP参数个数均为2。

举例:

输入 输出
(mul 3 -7) -21
(add 1 2) 3
(sub (mul 2 4) (div 9 3)) 5

二、输入描述

输入为长度不超过512的字符串,用例保证了无语法错误

三、输出描述

输出计算结果或者"error"。

四、解题思路

  1. 定义数字栈numStack,操作符栈operatorStack;
  2. 遍历输入的字符串input;
    • 如果是(,则操作符入栈;
    • 如果是计算标识符),数字入栈、弹出num2、弹出num1,通过加减乘除标识符计算;
    • 如果是空格,则数字入栈
  3. 输出数字栈最后数值。

五、Java算法源码

java 复制代码
public class OdTest {

    static Stack<Integer> numStack = new Stack<>();   // 数字栈
    static Stack<String> operatorStack = new Stack<>();  // 操作符栈

    // add/sub/mul/div
    // (div 15 (sub 45 40))
    // (sub (add 10 2) (mul 2 (div 10 2))) 2
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String input = sc.nextLine();
        int index = 0;
        int num1 = 0;
        int num2 = 0;
        for (int i = 0; i < input.length(); i++) {
            char ch = input.charAt(i);
            // 操作符
            if (ch == '(') {
                // 操作符入栈
                operatorStack.push(input.substring(i + 1, i + 4));
                i += 4;
                index = i + 1;
            } else if (ch == ')') {// 计算标识符
                if (index < i) {
                    // 数字入栈
                    numStack.push(Integer.parseInt(input.substring(index, i)));
                    i += 1;
                    index = i + 1;
                }
                // 弹出num2
                num2 = numStack.pop();
                // 弹出num1
                num1 = numStack.pop();
                // 计算
                calculate(num1, num2);
            } else {
                if (ch == ' ') {
                    if (index < i) {
                        // 数字入栈
                        numStack.push(Integer.parseInt(input.substring(index, i)));
                        index = i + 1;
                    }
                }
            }
        }

        while (operatorStack.size() != 0) {
            num2 = numStack.pop();
            num1 = numStack.pop();
            calculate(num1, num2);
        }

        System.out.println(numStack.get(0));
    }

    public static void calculate(int num1, int num2) {
        String op = operatorStack.pop();
        switch (op) {
            case "add":// 加
                numStack.push(num1 + num2);
                break;
            case "sub":// 减
                numStack.push(num1 - num2);
                break;
            case "mul":// 乘
                numStack.push(num1 * num2);
                break;
            case "div":// 除
                if (num2 == 0) {
                    System.out.println("error");
                    System.exit(0);
                } else {
                    int res = num1 / num2;
                    if (num1 % num2 != 0) {
                        if (res < 0) {
                            res -= 1;
                        } else {
                            res += 1;
                        }
                    }
                    numStack.push(res);
                }
                break;
            default:
                System.out.println("error");
                break;
        }
    }
}

六、效果展示

1、输入

(sub (add 10 2) (mul 2 (div 10 2)))

2、输出

2

3、说明

  1. 先计算div 10 2 = 5,表达式变为(sub (add 10 2) (mul 2 5))
  2. 再计算mul 2 5 = 10,表示式变为(sub (add 10 2) 10)
  3. 计算add 10 2 = 12,表示式变为(sub 12 10)
  4. 最后输出表示式(sub 12 10)结果2

🏆下一篇:华为OD机试 - 最长的顺子 - 感谢@禁止你发言提供的更简便算法(Java 2023 B卷 200分)

🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

相关推荐
xian_wwq12 小时前
【学习笔记】攻击链贯穿端边云!边缘网络访问三大核心风险预警
笔记·学习·安全·边缘计算
CoderYanger14 小时前
C.滑动窗口-求子数组个数-越长越合法——2799. 统计完全子数组的数目
java·c语言·开发语言·数据结构·算法·leetcode·职场和发展
C++业余爱好者14 小时前
Java 提供了8种基本数据类型及封装类型介绍
java·开发语言·python
想用offer打牌14 小时前
RocketMQ如何防止消息丢失?
java·后端·架构·开源·rocketmq
皮卡龙14 小时前
Java常用的JSON
java·开发语言·spring boot·json
利刃大大14 小时前
【JavaSE】十三、枚举类Enum && Lambda表达式 && 列表排序常见写法
java·开发语言·枚举·lambda·排序
float_六七15 小时前
Java反射:万能遥控器拆解编程
java·开发语言
han_hanker15 小时前
java 异常类——详解
java·开发语言
源码获取_wx:Fegn089515 小时前
基于springboot + vue健身房管理系统
java·开发语言·前端·vue.js·spring boot·后端·spring
深蓝海拓15 小时前
PySide6从0开始学习的笔记(一) 学前班
笔记·学习