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

相关推荐
(●—●)橘子……几秒前
3643.垂直翻转子矩阵 练习理解
笔记·python·学习·算法·leetcode·矩阵
Neoest1 分钟前
【Java 填坑日记】Excel里的“1.00“存入数据库解密后,Integer说它不认识:一次 NumberFormatException 翻车实录
java·数据库·excel
Ada大侦探1 分钟前
新手小白学习PowerBI第四弹--------RFM模型建模以及饼图、分解树、树状图、增长趋势图的可视化
人工智能·学习·数据分析·powerbi
小坏讲微服务2 分钟前
Spring Boot 4.0 新特性整合 MyBatis-Plus 完整教程
java·spring boot·后端·spring cloud·微服务·mybatis·mybatis plus
尚墨11113 分钟前
Java RestTemplate报错Invalid mime type “charset=utf-8“: does not contain ‘/‘
java·开发语言
我命由我123454 分钟前
Java 开发使用 MyBatis PostgreSQL 问题:传入的参数为 null,CONCAT 函数无法推断参数的数据类型
java·开发语言·数据库·学习·postgresql·mybatis·学习方法
爱装代码的小瓶子5 分钟前
【c++知识铺子】map和set的底层-红黑树
java·开发语言·c++
小蒜学长5 分钟前
基于Spring Boot家政服务系统的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端
洛阳泰山6 分钟前
Java实现周易六爻自动排盘:根据卜卦的时间推算出天干地支
java·开发语言·周易·六爻
黑岚樱梦6 分钟前
Git学习和Linux基础
git·学习