Discuss / Java / 进阶练习2

进阶练习2

Topic source

差不多弄懂了后缀表达式的求值,但是编译方法还是不理解,遇到计算优先级和括号脑袋就要炸了

进阶练习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;
	}
}

Faded-零

#2 Created at ... [Delete] [Delete and Lock User]

确实,括号真的不好整,难顶


  • 1

Reply