题解 | #表达式求值#
表达式求值
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; } }#栈的压入、弹出序列#