题解 | #表达式求值#
表达式求值
https://www.nowcoder.com/practice/9566499a2e1546c0a257e885dfdbf30d
import java.util.Scanner;
import java.util.Stack;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
String expression = in.nextLine();
StringBuilder postfixExpression = getPostfixExpression(expression);
String result = getResult(postfixExpression);
System.out.println(result);
}
}
private static String getResult(StringBuilder postfixExpression) {
Stack<String> executeStack = new Stack<>();
//暂存数字
StringBuilder tip = new StringBuilder();
for (int i = 0, len = postfixExpression.length(); i < len; i++) {
char tmp = postfixExpression.charAt(i);
//下面的判断中不用加上是否等于'.' 因为数字不会以.开头
//(tmp=='-'||tmp=='+')&&i<len-1&&postfixExpression.charAt(i+1)=='#' 是为了兼容正负号
if (((tmp >= '0') && (tmp <= '9')) || (tmp == '-' || tmp == '+') && i < len - 1 && postfixExpression.charAt(i + 1) == '#') {
int j = i;
while (j < len - 1) {
//tmp=postfixExpression.charAt(j) 这样赋值是为了避免正负号被当成运算符号,所以将正负数的最后一位当做tmp值
tip.append(tmp = postfixExpression.charAt(j));
if (postfixExpression.charAt(j + 1) == '#') {
//+2是因为隔了个#
j = j + 2;
} else {
break;
}
}
executeStack.push(tip.toString());
//清除缓存
tip.setLength(0);
//将游标设置到准确位置上
i = j;
}
//因为栈的特性先弹出的是运算符后面的数字所以要注意顺序
if (tmp == '+') {
Integer a = Integer.valueOf(executeStack.pop());
Integer b = Integer.valueOf(executeStack.pop());
executeStack.push(String.valueOf(b + a));
}
if (tmp == '-') {
Integer a = Integer.valueOf(executeStack.pop());
Integer b = Integer.valueOf(executeStack.pop());
executeStack.push(String.valueOf(b - a));
}
if (tmp == '*') {
Integer a = Integer.valueOf(executeStack.pop());
Integer b = Integer.valueOf(executeStack.pop());
executeStack.push(String.valueOf(b * a));
}
if (tmp == '/') {
Integer a = Integer.valueOf(executeStack.pop());
Integer b = Integer.valueOf(executeStack.pop());
executeStack.push(String.valueOf(b / a));
}
}
String result = executeStack.pop();
return Float.valueOf(result).intValue()+"";
}
private static StringBuilder getPostfixExpression(String expression) {
//清空空格
expression = expression.replaceAll(" ", "");
//表达式缓存
StringBuilder postfixExpression = new StringBuilder();
//运算符栈
Stack<Character> operatorStack = new Stack<>();
boolean isnum = false;
for (int i = 0; i < expression.length(); i++) {
char cur = expression.charAt(i);
//多位数字或小数数字用#链接
if (((cur >= '0') && (cur <= '9')) || (cur == '.')) {
if (isnum) {
postfixExpression.append("#");
}
postfixExpression.append(expression.charAt(i));
isnum = true;
continue;
} else {
//兼容数字前的正负标志
if (cur == '-' || cur == '+') {
//游标在刚开始或者前一位是左括号的时候就是正负号
if (i == 0 || expression.charAt(i - 1) == '(' || expression.charAt(i - 1) == '[') {
postfixExpression.append(expression.charAt(i));
isnum = true;
continue;
}
}
isnum = false;
}
switch (cur) {
case '[':
case '(':
//左括号无脑压入栈
operatorStack.push(cur);
break;
case ')': {
//遇到右括号在碰到左括号前无脑出栈
while (!operatorStack.empty()) {
if (operatorStack.peek() == '(') {
operatorStack.pop();
break;
} else {
postfixExpression.append(operatorStack.pop());
}
}
break;
}
case ']': {
//遇到右括号在碰到左括号前无脑出栈
while (!operatorStack.empty()) {
if (operatorStack.peek() == '[') {
operatorStack.pop();
break;
} else {
postfixExpression.append(operatorStack.pop());
}
}
break;
}
case '+':
case '-':
//栈为空直接压入
if (operatorStack.isEmpty()) {
operatorStack.push(cur);
break;
}
Character peek1 = operatorStack.peek();
//栈顶元素为左括号则压入
if (peek1 == '[' || peek1 == '(') {
operatorStack.push(cur);
break;
}
if (peek1 == '/' || peek1 == '*') {
//栈顶元素为乘除将栈顶元素弹出到表达式
postfixExpression.append(operatorStack.pop());
//当前运算符号为加减,运算符栈不为空的情况下依次比较元素(实际上就是直接弹出栈结束或者遇到左括号终止)
while (!operatorStack.isEmpty()) {
if (operatorStack.peek() == '(' || operatorStack.peek() == '[') {
break;
}
postfixExpression.append(operatorStack.pop());
}
operatorStack.push(cur);
break;
}
if (peek1 == '+' || peek1 == '-') {
//栈顶元素为加减 则弹出栈顶压入当前操作符
postfixExpression.append(operatorStack.pop());
operatorStack.push(cur);
break;
}
case '*':
case '/':
//栈为空直接压入
if (operatorStack.empty()) {
operatorStack.push(cur);
break;
}
Character peek = operatorStack.peek();
//栈顶元素为左括号或者加减则压入
if (peek == '+' || peek == '-'||peek == '('||peek=='[') {
operatorStack.push(cur);
break;
}
//栈顶为乘除的时候压入
if (peek == '*' || peek == '/') {
postfixExpression.append(operatorStack.pop());
operatorStack.push(cur);
}
break;
}
}
//中缀表达式循环结束,表达式栈还有操作符全部按顺序压入后缀表达式
while (!operatorStack.isEmpty()) {
postfixExpression.append(operatorStack.pop());
}
return postfixExpression;
}
}
#栈的压入、弹出序列#


