package com.donaldy.basic.expr; import com.donaldy.basic.Stack; /** * 针对最后一个用例,expr: 10 - 30 + 50; * 负数,直接对后面的数进行取反(实际上计算机就是这样做的,组原有提。) * 即:expr: 10 - 30 + 50 * 处理后: 10 + -30 + 50 */ public class InfixExpr { String expr = null; Stack numStack = new Stack(); Stack symbolStack = new Stack(); public InfixExpr(String expr) { this.expr = expr; } public float evaluate() { if (!this.numStack.isEmpty()) return (float) this.numStack.peek(); char [] arr = this.expr.toCharArray(); parseCharArray(arr); remainOperate(); return (float) this.numStack.peek(); } private void parseCharArray(char [] arr) { for (int i = 0; i < arr.length; ) { i = parseNumberReturnIndex(i, arr); if (i >= arr.length) break; i = parseSymbolReturnIndex(i, arr); } } private int parseNumberReturnIndex(int index, char [] arr) { if (arr[index] <= '9' && arr[index] >= '0' ) { float value = arr[index ++] - '0'; while (index < arr.length && arr[index] <= '9' && arr[index] >= '0' ) { value *= 10; value += arr[index] - '0'; index ++; } this.numStack.push(value); } return index; } private int parseSymbolReturnIndex(int index, char[] arr) { if ("+-*/".contains(arr[index] + "")) { char operator = arr[index ++]; if (operator == '+') { this.symbolStack.push('+'); } if (operator == '-') { this.symbolStack.push('+'); float value = arr[index ++] - '0'; while (index < arr.length && arr[index] <= '9' && arr[index] >= '0') { value *= 10; value += arr[index] - '0'; index ++; } this.numStack.push(-value); } if (operator == '*' || operator == '/') { float value1 = (float) this.numStack.pop(); float value2 = arr[index ++] - '0'; while (index < arr.length && arr[index] <= '9' && arr[index] >= '0') { value2 *= 10; value2 += arr[index] - '0'; index ++; } this.numStack.push(operate(value2, value1, operator)); } } return index; } private void remainOperate() { while (!this.symbolStack.isEmpty()) { if (this.numStack.size() < 2 || this.symbolStack.size() < 1) throw new IndexOutOfBoundsException("numStack.size : " + this.numStack.size() + " symbolStack.size : " + this.symbolStack.size()); float value1 = (float) this.numStack.pop(); float value2 = (float) this.numStack.pop(); char cSymbol = (char) this.symbolStack.pop(); this.numStack.push(operate(value1, value2, cSymbol)); } } private float operate (float value1, float value2, char operator) { if (operator == '+') { return value2 + value1; } else if (operator == '*') { return value2 * value1; } else if (operator == '/') { return value2 / value1; } else { throw new RuntimeException("No this operator : " + operator); } } }