目录
- 专栏导读
- 一、题目描述
- 二、输入描述
- 三、输出描述
- 四、解题思路
- 五、Java算法源码
- 六、效果展示
- 1、输入
- 2、输出
- 3、说明
华为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”。
四、解题思路
- 定义数字栈numStack,操作符栈operatorStack;
- 遍历输入的字符串input;
- 如果是(,则操作符入栈;
- 如果是计算标识符),数字入栈、弹出num2、弹出num1,通过加减乘除标识符计算;
- 如果是空格,则数字入栈
- 输出数字栈最后数值。
五、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、说明
- 先计算div 10 2 = 5,表达式变为(sub (add 10 2) (mul 2 5))
- 再计算mul 2 5 = 10,表示式变为(sub (add 10 2) 10)
- 计算add 10 2 = 12,表示式变为(sub 12 10)
- 最后输出表示式(sub 12 10)结果2
🏆下一篇:华为OD机试 - 最长的顺子 - 感谢@禁止你发言提供的更简便算法(Java 2023 B卷 200分)
🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。