逆波兰表达式原理实现
2017-11-10 16:33
239 查看
解析原理如下:(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");
相关文章推荐
- C指针原理(32)-编译原理-逆波兰表达式及其实现
- Java 8 动态类型语言Lambda表达式实现原理解析
- Leetcode 150:Evaluate Reverse Polish Notation(计算逆波兰表达式) --java实现
- c++实现将表达式转换为逆波兰表达式
- C++逆波兰表达式转化实现简单计算器
- 逆波兰表达式实现
- c# 数学表达式分析(采用逆波兰方式实现)
- 逆波兰表达式的实现(也叫后缀表达式)
- 数据结构之用栈实现逆波兰表达式
- 逆波兰表达式的c++实现
- 【Algorithm】逆波兰表达式 Java实现
- 24点算法 | 逆波兰表达式实现去重复
- LeetCode 逆波兰表达式java实现
- Atitit.sql ast 表达式 语法树 语法 解析原理与实现 java php c#.net js python
- 逆波兰表达式的实现
- Java 8 动态类型语言Lambda表达式实现原理分析
- 3*(4+6)-7 # 用代码实现这个运算表达式,仅包含逆波兰式部分,算术结果部分未写出
- Reverse Polish Notation用堆栈实现逆波兰表达式
- C++实现 逆波兰表达式计算问题
- 一个逆波兰表达式实现的四则混合运算计算器