解析原理如下:
(1) 该运算符为左括号"(",则直接存入运算符堆栈。
(2) 该运算符为右括号")",则输出运算符堆栈中的运算符到操作数堆栈,直到遇到左括号为止,此时抛弃该左括号。
(3) 该运算符为非括号运算符:
(a) 若运算符堆栈栈顶的运算符为左括号,则直接存入运算符堆栈。
(b) 若比运算符堆栈栈顶的运算符优先级高,则直接存入运算符堆栈。
(c) 若比运算符堆栈栈顶的运算符优先级低或相等,则输出栈顶运算符到操作数堆栈,直至运算符栈栈顶运算符低于(不包括等于)该运算符优先级,或为左括号,
并将当前运算符压入运算符堆栈。
具体实现:
package com.example.admin.myapplication; import android.os.Build; import android.support.annotation.RequiresApi; import android.text.TextUtils; import android.util.Log; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Stack; /** * Created by admin on 2017/11/8. * 逆波兰算法实现 * 仅支持 + - * / */ public class NBLArithmetic { private enum Operator { ADD("+", 1), SUBJECT("-", 1), RIDE("*", 2), DIVIDE("/", 2), BRACKET_L("(", 0), BRACKET_R(")", 0),; Operator(String value, int weight) { this.value = value; this.weight = weight; } String value; int weight; public String getValue() { return value; } public int getWeight() { return weight; } static Operator fromValue(String value) { Operator[] values = values(); for (Operator val : values) { if (value.equals(val.getValue())) { return val; } } return null; } } /** * 运算符栈 */ private Stack<Operator> operatorStack; /** * 操作数栈 */ private Stack<Integer> operandStack; /** * 临时存储区,存放逆波兰运算中间结果 */ private LinkedList<String> cacheQueue; @RequiresApi(api = Build.VERSION_CODES.GINGERBREAD) public NBLArithmetic() { operatorStack = new Stack<>(); operandStack = new Stack<>(); cacheQueue = new LinkedList<>(); } /** * 计算结果 * * @param operation */ public void opera(String operation) { List<String> operas = getArrayFormOperation(operation); for (String opera : operas) { if (TextUtils.isDigitsOnly(opera)) { cacheQueue.add(opera); } else { Operator operator = Operator.fromValue(opera); Operator lastOperator = operatorStack.empty() ? null : operatorStack.peek(); if (lastOperator == null || lastOperator == Operator.BRACKET_L || operator == Operator.BRACKET_L) { operatorStack.push(operator); } else { switch (operator) { case ADD: case RIDE: case DIVIDE: case SUBJECT: while (lastOperator != null && operator.getWeight() <= lastOperator.getWeight()) {//栈顶优先级大于等于本次操作符 cacheQueue.add(operatorStack.pop().getValue()); lastOperator = operatorStack.empty() ? null : operatorStack.peek(); } operatorStack.push(operator); break; case BRACKET_R: while (lastOperator != null && lastOperator != Operator.BRACKET_L) { cacheQueue.add(operatorStack.pop().getValue()); lastOperator = operatorStack.empty() ? null : operatorStack.peek(); } operatorStack.pop(); break; } } } } while (!operatorStack.isEmpty()) { cacheQueue.add(operatorStack.pop().getValue()); } //-----------------------开始计算--------------------------------------------------- while (cacheQueue.size() > 0) { String data = cacheQueue.removeFirst(); if (TextUtils.isDigitsOnly(data)) { operandStack.push(Integer.parseInt(data)); } else { Operator operator = Operator.fromValue(data); int b = operandStack.pop(); int a = operandStack.pop(); switch (operator) { case ADD: operandStack.push(a + b); break; case RIDE: operandStack.push(a * b); break; case DIVIDE: operandStack.push(a / b); break; case SUBJECT: operandStack.push(a - b); break; } } } Log.i("NBL", operation + " = " + operandStack.pop()); } /** * 解析表达式成array * * @param operation * @return */ private List getArrayFormOperation(String operation) { List operaList = new ArrayList(); char[] chars = operation.toCharArray(); StringBuffer sb = new StringBuffer(); for (char a : chars) { if (TextUtils.isDigitsOnly(a + "")) { sb.append(a + ""); } else if (".".equals(a + "")) { sb.append(a + ""); } else { if (sb.length() > 0) { operaList.add(sb.toString()); } operaList.add(a + ""); sb.delete(0, sb.length()); } } if (sb.length() > 0) { operaList.add(sb.toString()); } return operaList; } }
使用很方便:
new NBLArithmetic().opera("3+4*(3-5)*2"); new NBLArithmetic().opera("3+4*(3-5)*2+56"); new NBLArithmetic().opera("3+4*(3-5)*2+56-3*2"); new NBLArithmetic().opera("3+4*(3-5)*2+56-3*2+(2-8)*4"); new NBLArithmetic().opera("56-3+(2-8)*4"); new NBLArithmetic().opera("3+4*(3-5)*2+56-3*2+(2-8)*4");