package algorithm.expression; class Token { public static final String OP_ADD = "+"; public static final String OP_SUB = "-"; public static final String OP_MUL = "*"; public static final String OP_DIV = "/"; public static final String OP_POWER= "^"; public static final String OP_L_BRACKET = "("; public static final String OP_R_BRACKET = ")"; public static final String OP_SCOPE = "#"; public static final int OPERATOR = 1; public static final int NUMBER = 2; public static final Token ADD = new Token(OPERATOR, OP_ADD); public static final Token SUB = new Token(OPERATOR, OP_SUB); public static final Token MUL = new Token(OPERATOR, OP_MUL); public static final Token DIV = new Token(OPERATOR, OP_DIV); public static final Token POWER = new Token(OPERATOR, OP_DIV); public static final Token L_BRACKET = new Token(OPERATOR, OP_L_BRACKET); public static final Token R_BRACKET = new Token(OPERATOR, OP_R_BRACKET); public static final Token SCOPE = new Token(OPERATOR, OP_SCOPE); //优先级表 private static int[][] priorities = { //+ - * / ^ ( ) # {-1, -1, -1, -1, -1, 1, -1, 1}, // + {-1, -1, -1, -1, -1, 1, -1, 1}, // - { 1, 1, -1, -1, -1, 1, -1, 1}, // * { 1, 1, -1, -1, -1, 1, -1, 1}, // / { 1, 1, 1, 1, -1, 1, -1, 1}, // ^ { 1, 1, 1, 1, 1, 1, -1, 1}, // ( {-1, -1, -1, -1, -1, -1, 0, 1}, // ) {-1, -1, -1, -1, -1, -1, -1, 0} // # }; String value; int type; public Token(int type, String value){ this.type = type; this.value = value; } public boolean isNumber() { return type == NUMBER; } public boolean isOperator() { return type == OPERATOR; } public float getFloatValue() { return Float.valueOf(value); } public String toString(){ return value; } private static int indexOf(String op) { switch (op) { case OP_ADD: return 0; case OP_SUB: return 1; case OP_MUL: return 2; case OP_DIV: return 3; case OP_POWER: return 4; case OP_L_BRACKET: return 5; case OP_R_BRACKET: return 6; case OP_SCOPE: return 7; } return 0; } public static int compare(Token op, Token peek) { int opIndex = indexOf(op.toString()); int peekIndex = indexOf(peek.toString()); return priorities[opIndex][peekIndex]; } public static Token calculate(Token num1, Token op, Token num2) { float result = 0.0f; float n1 = num1.getFloatValue(); float n2 = num2.getFloatValue(); switch (op.toString()) { case OP_ADD: result = n1 + n2; break; case OP_SUB: result = n1 - n2; break; case OP_MUL: result = n1 * n2; break; case OP_DIV: if (n2 == 0) { throw new RuntimeException("Divide by 0"); } result = n1 / n2; break; case OP_POWER: result = (float) Math.pow(n1, n2); break; } return new Token(NUMBER, result + ""); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Token token = (Token) o; return type == token.type && (value != null ? value.equals(token.value) : token.value == null); } @Override public int hashCode() { int result = value != null ? value.hashCode() : 0; result = 31 * result + type; return result; } }