牛客 - HJ50 四则运算 - AC CODE
1.洛谷 - P1957 口算练习题 - AC CODE
2.牛客 - HJ50 四则运算 - AC CODE
牛客 - HJ50 四则运算
描述
对于输入的表达式,保证其形式合法,计算过程中全程合法,计算过程中不需要使用到实数。
结果 ans 在 [-1000, 1000]
范围内。
直接输出计算结果。
保证表达式字符串由 0-9 的数字、加法'+'、减法'-'、乘法'*'、除法'/'、小括号'()'、中括号'[]'、大括号'{}'组成,且运算符之间没有空格。
输入描述
输入一个长度在 [1, 1000]
范围、由题面所述符号构成的字符串,代表一个表达式。
输出描述
输出一个整数 ans,代表计算的答案,答案满足 [-1000, 1000]
范围
示例
输入
3+2*{1+2*[-4/(8-6)+7]}
输出
25
AC CODE
思路
- 第一个出现的数字和符号直接入栈
- 遇到数字直接入栈
- 遇到符号,先判断当前符号和栈顶符号的运算优先级,栈顶优先级更高,则取数字栈的2个栈顶运算;当前符号优先级更高则入栈
- 最后反复取数字栈的2个栈顶和符号栈栈顶运算,直到符号栈为空或只剩下一个数字
AC CODE
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class HJ50 {
public static Integer Calculate(Character op, Integer a, Integer b) { // 运算函数
if (op == '-') {
return a - b;
} else if (op == '+') {
return a + b;
} else if (op == '*') {
return a * b;
} else {
return a / b;
}
}
public static boolean ComparOpFirst(Character top, Character op) { // 符号优先级判断,当前符号优先级大于栈顶,返回true
if (top == '(') { // '('的优先级最高
return true;
} else if (op == '+' || op == '-') { // + - 的优先级最低
return false;
} else if (op == '*' || op == '/') { // * / 的优先级只比'('低,'('后的第一个操作符一定会入栈,所以 * / 不会与'('比较
return true;
} else { // 默认true
return true;
}
}
public static void main(String[] args) {
String strt = new String();
try (Scanner scanner = new Scanner(System.in)) {
strt = scanner.nextLine(); // 算式输入
}
// 输入数据处理,括号替换只是为了方便处理
strt = strt.replace('{', '(');
strt = strt.replace('}', ')');
strt = strt.replace('[', '(');
strt = strt.replace(']', ')');
List<Integer> nums = new ArrayList<>(); // 数据栈
List<Character> ops = new ArrayList<>(); // 符号栈
boolean opFlag = true; // 第一个符号标记
String data = new String(); // 数字str,使用String拼接数字,以便使用valueOf方法
data = ""; // 初始化
for (int h = 0; h < strt.length(); h++) {
if (strt.charAt(h) >= '0' && strt.charAt(h) <= '9') { // 当前是数字时向后遍历,直到遍历出非数字
while (h < strt.length() && strt.charAt(h) >= '0' && strt.charAt(h) <= '9') { // 数字识别
data += strt.charAt(h);
h++; // 此处直接h++遍历数字,后续被操作的就是符号
}
nums.add(Integer.valueOf(data)); // 数字入栈
if (h >= strt.length()) { // 遍历到算式末尾了
break;
}
}
if (strt.charAt(h) == '-') { // 减号特殊处理
if (h == 0 || strt.charAt(h - 1) == '(') { // 表示负号,负号只出现在算式开头或'('之后,默认当算式中出现负数时,需要加小括号
data += strt.charAt(h);
continue; // 跳过,直接识别下一字符,下一字符一定是数字
}
}
data = ""; // 数字重置,因为前面已经遍历到非数字位时才会停止,因此每次遍历完都要数字String重置
if (opFlag) { // 第一个四则运算符还没入栈
opFlag = false;
ops.add(strt.charAt(h)); // 直接入栈
continue; // 跳过
}
if (strt.charAt(h) == '(') {
ops.add(strt.charAt(h)); // 左括号直接入栈
opFlag = true; // 左括号入栈后,要重新入栈括号后第一次出现的操作符
continue; // 跳过
}
if (strt.charAt(h) != ')') { // 遇到四则运算符
if (ComparOpFirst(ops.get(ops.size() - 1), strt.charAt(h))) { // 操作符优先级高于栈顶
ops.add(strt.charAt(h)); // 入栈
} else { // 栈顶优先级更高,需要运算栈顶
// 反复运算栈顶,直到栈空或者栈顶的优先级低于当前,只运算栈顶后就跳出,会有这种情况
// 比如出现 + / - 的操作组合,运算完 / 之后,运算完 + 才能运算 -
while (nums.size() >= 2 && ops.size() != 0
&& (!ComparOpFirst(ops.get(ops.size() - 1), strt.charAt(h)))) {
// 取数字栈顶的两个元素
Integer b = nums.get(nums.size() - 1);
nums.remove(nums.size() - 1);
Integer a = nums.get(nums.size() - 1);
nums.remove(nums.size() - 1);
// 取符号栈顶
Character op = ops.get(ops.size() - 1);
ops.remove(ops.size() - 1);
Integer tAnser = Calculate(op, a, b); // 运算
nums.add(tAnser); // 结果入栈
}
ops.add(strt.charAt(h)); // 操作符入栈
}
}
if (strt.charAt(h) == ')') { // 遇到')'则反复运算栈顶,直到遇到'('或者空栈
while (nums.size() >= 2 && ops.size() != 0 && ops.get(ops.size() - 1) != '(') {
// 取数字栈顶的两个元素
Integer b = nums.get(nums.size() - 1);
nums.remove(nums.size() - 1);
Integer a = nums.get(nums.size() - 1);
nums.remove(nums.size() - 1);
// 取符号栈顶
Character op = ops.get(ops.size() - 1);
ops.remove(ops.size() - 1);
Integer tAnser = Calculate(op, a, b); // 运算
nums.add(tAnser); // 结果入栈
}
ops.remove(ops.size() - 1); // 左括号出栈
}
}
while (nums.size() >= 2) { // 数字栈里面还有数字,则反复运算到只剩一个数字
// 取数字栈顶的两个元素
Integer b = nums.get(nums.size() - 1);
nums.remove(nums.size() - 1);
Integer a = nums.get(nums.size() - 1);
nums.remove(nums.size() - 1);
// 取符号栈顶
Character op = ops.get(ops.size() - 1);
ops.remove(ops.size() - 1);
Integer tAnser = Calculate(op, a, b); // 运算
nums.add(tAnser); // 结果入栈
}
System.out.println(nums.get(0));
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix