题解 | #表达式求值#
表达式求值
https://www.nowcoder.com/practice/9566499a2e1546c0a257e885dfdbf30d
这道题,其实和leetCode.394差不太多,要稍微难一点。
我们主要要知道有哪几种情况:1.数字 2.括号 3.运算符。总的来说其实就是这三种
先说说数字,简单举个例子:30+2
首先,我们要考虑到出现非个位数的情况,将其进行组装。
接着我们要知道运算符是什么,当前是+号,那么说明我们之前收集到的数字是可以和后面的数之前累加的,所以我们先将其放入栈中。
接着遍历到2这个字符,我们还是会设置一个变量去赋值。但此时我们要考虑到一点,就是它已经处于最后一位了。咱们需要进行计算了,需要将其放入栈中了。所以这里我们需要判断当前的下标是否是处于最后一位(i==length-1)
再来看看括号我们怎么处理,大家其实都知道,如果在表达式中出现括号,那么肯定是需要先进行计算的。所以呢,需要将括号中的表达式提取出来进行计算,然后返回结果。
比如:2*(3+2)+(5-1)
我们首先需要定位括号的范围,也就是下标的范围是多少。所以咱们需要定位"("和")"。所以遇到"("就加1,")"就减1.如果等于0了,说明其中一个括号表达式中的范围我们找到了。
最后来看看运算符,加减乘除。
比如说:50-2
之前咱们说过了,会考虑非个位数的数字。首先我们已经将50这个数字组装好了,然后接着遍历到"-"减号这个位置。但是这里我们要考虑一个问题,就是需要把之前收集的数字先放到栈中去。所以呢,我们默认设置符号是加号,如果是加号,那么直接将数字放入栈中。放好之后,我们要考虑怎么让50和2进行减法运算。所以在放入栈中之后,我们需要将符号进行替换,此时从+变成了- 。 OK,接着遍历,这个时候已经遍历到2这个字符了。此时已经是最后一位了,我们需要运算。所以需要将2也放入栈中,由于此时符号已经被替换为了减号。所以我们将 2*-1 的结果放入栈中。
乘除也是一样的,因为乘除的优先级比加减要高。所以我们将之前放入栈中的前一个数字出栈,与当前的数字直接进行乘/除运算。将结果在丢入栈中即可
我们得到栈的结果之后,让其进行出栈。然后运算(这里建议默认使用加法运算)
import java.util.*; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 System.out.println(getVal(in.nextLine())); } private static int getVal(String str) { // 计算题 3+2-5 // 1.数字处理 2.括号处理 3.+-*/处理 // 存放数字 Stack<Integer> stack = new Stack<>(); int num = 0; // 默认是+号 char sign = '+'; // 注意下标越界 char[] chars = str.toCharArray(); int n = chars.length; for (int i = 0; i < chars.length; i++) { char cVal = chars[i]; if (Character.isDigit(cVal)) { // 组装数字 num = num * 10 + Integer.valueOf(String.valueOf(cVal)); } else if (cVal == '(') { int j = i + 1; int count = 1; while (count > 0) { if (chars[j] == ')') count--; if (chars[j] == '(') count++; j++; } // 得到括号中的数据进行处理 num = getVal(str.substring(i + 1, j - 1)); // 将下标修改 此时代表括号。由于下次循环会自动+1,所以不用j i = j - 1; } // i==n-1是为了让其进行运算。这里使用if的原因也是如此 if (!Character.isDigit(cVal) || i == n - 1) { // 如果是运算符 if (sign == '+') { stack.push(num); } else if (sign == '-') { stack.push(num * -1); } else if (sign == '*') { stack.push(stack.pop() * num); } else if (sign == '/') { stack.push(stack.pop() / num); } // 替换符号 sign = cVal; // 将num置空 num = 0; } } int ans = 0; while (!stack.isEmpty()) { ans += stack.pop(); } return ans; } }