差不多弄懂了后缀表达式的求值,但是编译方法还是不理解,遇到计算优先级和括号脑袋就要炸了
进阶练习2不比进阶练习难很多,无非就是复习下Map的使用。但是进阶练习比第一个练习难很多啊。
package com.itranswarp.learnjava; import java.util.*; /** * Learn Java from https://www.liaoxuefeng.com/ * * @author liaoxuefeng */ public class Main { public static void main(String[] args) { String exp = "x + 2 * (y - 5)"; SuffixExpression se = compile(exp); Map<String, Integer> env = Map.of("x", 1, "y", 9); int result = se.execute(env); System.out.println(env); System.out.println(exp + " = " + result + " " + (result == 1 + 2 * (9 - 5) ? "✓" : "✗")); } static SuffixExpression compile(String exp) { Deque<Character> s1 = new ArrayDeque<>(); Deque<Character> s2 = new ArrayDeque<>(); for (char ch : exp.toCharArray()) { if (Decider.isNumber(ch)) { s2.push(ch); } else if (Decider.isOperator(ch)) { while (true) { if (s1.isEmpty() || s1.peek() == '(') { s1.push(ch); break; } else if (Decider.comparePri(ch, s1.peek())) { s1.push(ch); break; } else { s2.push(s1.pop()); } } } else if (ch == '(') { s1.push(ch); } else if (ch == ')') { while (true) { if (s1.peek() == '(') { s1.pop(); break; } else { s2.push(s1.pop()); } } } } while (!s1.isEmpty()) { s2.push(s1.pop()); } char[] expArray = new char[s2.size()]; for (int i = expArray.length - 1; !s2.isEmpty(); i--) { expArray[i] = s2.pop(); } return new SuffixExpression(expArray); } } class SuffixExpression { private char[] expArray; public SuffixExpression(char[] expArray) { this.expArray = expArray; } int execute(Map<String, Integer> env) { // TODO: Deque<Integer> stack = new ArrayDeque<>(); for (char ch : expArray) { if (Decider.isConstant(ch)) { stack.push(ch - 48); } else if (Decider.isVariable(ch)) { String key = new StringBuilder().append(ch).toString(); stack.push(env.get(key)); } else if (Decider.isOperator(ch)) { int top = stack.pop(); int subtop = stack.pop(); stack.push(calc(subtop, ch, top)); } } if (stack.size() == 1) { return stack.pop(); } //此处代码应不可达 return 0; } private Integer calc(int e1, char operator, int e2) { if (operator == '+') { return e1 + e2; } else if (operator == '-') { return e1 - e2; } else if (operator == '*') { return e1 * e2; } else if (operator == '/') { return e1 / e2; } //此处代码应不可达 return null; } } class Decider { public static boolean isConstant(char ch) { return (ch > '0' && ch < '9'); } public static boolean isVariable(char ch) { return (ch > 'a' && ch < 'z'); } public static boolean isNumber(char ch) { return (isConstant(ch) || isVariable(ch)); } public static boolean isOperator(char ch) { return (ch == '+' || ch == '-' || ch == '*' || ch == '/'); } public static boolean comparePri(char op1, char op2) { if (op1 == '*' || op1 == '/') { return (op2 == '+' || op2 == '-'); } return false; } }
确实,括号真的不好整,难顶
Sign in to make a reply
SNH48-刘慈欣
差不多弄懂了后缀表达式的求值,但是编译方法还是不理解,遇到计算优先级和括号脑袋就要炸了
进阶练习2不比进阶练习难很多,无非就是复习下Map的使用。但是进阶练习比第一个练习难很多啊。