题解 | #表达式求值#
表达式求值
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;
}
}
查看11道真题和解析