华为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在线答疑。

相关推荐
llwszx3 小时前
深入理解Java锁原理(一):偏向锁的设计原理与性能优化
java·spring··偏向锁
云泽野3 小时前
【Java|集合类】list遍历的6种方式
java·python·list
二进制person4 小时前
Java SE--方法的使用
java·开发语言·算法
小阳拱白菜5 小时前
java异常学习
java
FrankYoou6 小时前
Jenkins 与 GitLab CI/CD 的核心对比
java·docker
麦兜*6 小时前
Spring Boot启动优化7板斧(延迟初始化、组件扫描精准打击、JVM参数调优):砍掉70%启动时间的魔鬼实践
java·jvm·spring boot·后端·spring·spring cloud·系统架构
KK溜了溜了6 小时前
JAVA-springboot 整合Redis
java·spring boot·redis
天河归来7 小时前
使用idea创建springboot单体项目
java·spring boot·intellij-idea
weixin_478689767 小时前
十大排序算法汇总
java·算法·排序算法
码荼7 小时前
学习开发之hashmap
java·python·学习·哈希算法·个人开发·小白学开发·不花钱不花时间crud