表达式求值
- 1.题目
- 2.基本思想
- 3.代码实现
1.题目
给定一个表达式,其中运算符仅包含 +,-,*,/
(加 减 乘 整除),可能包含括号,请你求出表达式的最终值。
注意:
- 数据保证给定的表达式合法。
- 题目保证符号 - 只作为减号出现,不会作为负号出现,例如,
-1+2
,(2+2)*(-(1+1)+2)
之类表达式均不会出现。 - 题目保证表达式中所有数字均为正整数。
- 题目保证表达式在中间计算过程以及结果中,均不超过 2^31−1。
- 题目中的整除是指向 0 取整,也就是说对于大于 0的结果向下取整,例如 5/3=1,对于小于 0 的结果向上取整,例如 5/(1−4)=−1。
- C++和Java中的整除默认是向零取整;Python中的整除//默认向下取整,因此Python的eval()函数中的整除也是向下取整,在本题中不能直接使用。
输入格式
共一行,为给定表达式。
输出格式
共一行,为表达式的结果。
数据范围
表达式的长度不超过 1 0 5 。 表达式的长度不超过 10^5。 表达式的长度不超过105。
所有操作保证合法。 所有操作保证合法。 所有操作保证合法。
输入样例:
(2+2)*(1+1)
输出样例:
8
2.基本思想
基本思路:针对这一问题,我们运算的时候是考虑运算符优先级问题的,那么就得把优先级高的数据先处理,很自然地就选择了栈来倒序。
我们人在做这样计算题的时候,往往也是先去寻找乘除先计算,写出计算结果,最后再看加减运算,那么自然乘除比加减高上一级,在此之上是括号
在这个思路上,去看代码就更为容易看懂了
3.代码实现
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Stack;public class Main {static Stack<Integer> num = new Stack<>();static Stack<Character> opt = new Stack<>();static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));private static void eval() {//计算int num1 = num.pop();int num2 = num.pop();char x = opt.pop();if (x == '*') num.push(num1 * num2);else if (x == '/') num.push(num2 / num1);else if (x == '+') num.push(num2 + num1);else if (x == '-') num.push(num2 - num1);}public static void main(String[] args) throws IOException {String s = br.readLine();int len = s.length();HashMap<Character, Integer> map = new HashMap<>();map.put('+', 1);map.put('-', 1);map.put('*', 2);map.put('/', 2);for (int i = 0; i < len; i++) {char c = s.charAt(i);//取出每个 opt 或者 numif (Character.isDigit(c)) {int x = 0, j = i;//检查当前字符是否是数字且没有超出字符串的长度: 由于输入数字可能是多位数,使用 x * 10 来将之前的数字向左移动一位,然后加上当前字符对应的数字值while (j < len && Character.isDigit(s.charAt(j))) x = x * 10 + s.charAt(j++) - '0';num.push(x);i = j - 1;} else if (s.charAt(i) == '(') {opt.push(s.charAt(i));} else if (s.charAt(i) == ')') {while (opt.peek() != '(') eval();opt.pop();} else if (opt.isEmpty()) {opt.push(s.charAt(i));} else {//运算符非空 并且 栈顶元素的优先级 大于 当前元素的优先级while (opt.size() != 0 && opt.peek() != '(' && (map.get(opt.peek()) >= map.get(s.charAt(i)))) eval();opt.push(s.charAt(i));}}while (opt.size() > 0) eval();System.out.println(num.peek());}
}