java 栈 Stack类 栈的应用--中缀表达式转后缀表达式并计算
2017-03-04 16:38
453 查看
package com.test; import java.math.BigDecimal; import java.util.Stack; /** * 利用栈实现中缀表达式转后缀表达式,并提供对后缀表达式的计算 * Created by jockiller on 2016/3/4. */ public class BiaoDaShi { public static void main(String[] args) { String bds = "60/(5-2) + 5 *(20 *(3-1))"; System.out.println(bds); String hzBds = revertBds(bds); System.out.println(hzBds); BigDecimal res = calculate(hzBds); System.out.println(res); } /** * 对后缀表达式进行计算 * @param hzBds * @return */ private static BigDecimal calculate(String hzBds) { Stack<BigDecimal> stack = new Stack<>(); String[] split = hzBds.split(" "); for (String s : split) { if (null == s || "".equals(s.trim())) continue; if (YunSuanFu.isYunSuanFu(s.charAt(0))){ //如果是运算符 则将堆中的两个值拿出来计算 然后放回堆中 stack.push(stackoperate(stack.pop(),stack.pop(),s.charAt(0))); }else { stack.push(new BigDecimal(s)); } } return stack.pop(); } /** * 根据运算符进行计算 * @param v1 * @param v2 * @param c * @return */ private static BigDecimal stackoperate(BigDecimal v2, BigDecimal v1, char c) { YunSuanFu yun = YunSuanFu.parse(c); switch (yun){ case MULTIPLY: return v2.multiply(v1); case DIVIDE: return v1.divide(v2); case ADD: return v1.add(v2); case MINUS: return v1.subtract(v2); default: throw new RuntimeException("不支持的运算"); } } /** * 中缀表达式转换为后缀表达式 * * @param bds 中缀表达式 * @return */ private static String revertBds(String bds) { Stack<Character> stack = new Stack(); String s = bds.replaceAll(" ", ""); StringBuffer sb = new StringBuffer(); boolean nextPop = false; char ic; for (int i = 0; i < s.length(); i++) { if (YunSuanFu.isYunSuanFu(ic = s.charAt(i))) { if (nextPop) { nextPop = false; sb.append(" ").append(stack.pop()); sb.append(" ").append(stack.pop()); } //判断当前运算符是否是右括号 if (ic == YunSuanFu.RIGHT.ele) { //将栈中上一个左括号之前的运算符出栈 while (true) { if ((ic = stack.pop()) != YunSuanFu.LEFT.ele) { sb.append(" ").append(ic); } else { // 如果左括号之前的一个运算符是或者除 那么也需要出栈 if (stack.peek() == YunSuanFu.DIVIDE.ele || stack.peek() == YunSuanFu.MINUS.ele) { sb.append(" ").append(stack.pop()); } break; } } } else if (stack.size() > 1 && YunSuanFu.isPriorityHigh(ic, stack.peek())) { //判断当前栈中是否有一个运算符 并且新运算符的优先级高于当前优先级,如果是 则下一位的数字输出 并将栈中的两个运算符出栈 nextPop = true; stack.push(ic); sb.append(" "); } else { //如果是运算符 则入栈 stack.push(ic); sb.append(" "); } } else { sb.append(ic); } if (i == s.length() - 1) { int size = stack.size(); for (int j = 0; j < size; j++) { sb.append(" ").append(stack.pop()); } } } return sb.toString(); } private enum YunSuanFu { ADD('+'), MINUS('-'), MULTIPLY('*'), DIVIDE('/'), LEFT('('), RIGHT(')'),; private char ele; YunSuanFu(char ele) { this.ele = ele; } /** * 判断是不是运算符 * * @param c * @return */ public static boolean isYunSuanFu(char c) { for (YunSuanFu fu : YunSuanFu.values()) { if (fu.ele == c) { return true; } } return false; } /** * 转换运算符 * * @param c * @return */ public static YunSuanFu parse(char c) { for (YunSuanFu fu : YunSuanFu.values()) { if (fu.ele == c) { return fu; } } throw new RuntimeException("未知运算符"); } /** * 判断第一个运算符优先级是否高于第二个 * * @param c1 * @param c2 * @return */ public static boolean isPriorityHigh(char c1, char c2) { if ((c1 == MULTIPLY.ele || c1 == DIVIDE.ele) && (c2 == ADD.ele || c2 == MINUS.ele)) { return true; } return false; } } }
相关文章推荐
- Java堆栈的应用2----------中缀表达式转为后缀表达式的计算Java实现
- java中的栈Stack的基本使用和应用(二) ——利用栈计算合法的算术表达,中缀表达式转后缀表达式
- java实现中缀表达式转后缀表达式并且计算
- 栈应用之中缀转后缀表达式计算(C++、JAVA)
- java实现中缀表达式转后缀表达式并且计算
- Java 中缀表达式转后缀表达式 + 中/后缀表达式计算
- 栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)
- java实现中缀表达式转后缀表达式并且计算
- 数据结构—中缀表达式转后缀表达式算法及实现—栈的应用—计算表达式(C++代码实现)(1)
- Java实现中缀表达式转后缀表达式并计算结果
- java实现中缀表达式转后缀表达式并且计算
- 栈应用(中缀表达式转后缀表达式并计算后缀表达式的值)
- java实现中缀表达式转后缀表达式并且计算
- 中缀表达式转后缀表达式及后缀表达式的计算
- 中缀表达式/前缀表达式/后缀表达式 的计算方法
- 栈的应用-中缀表达式转后缀表达式(C版)
- 数据结构之应用 "栈(Stack)" 实现: 解析算术表达式及计算求值 (C#/Java)
- 【算法】中缀表达式、后缀表达式的java实现几网上观点的勘误。
- 堆栈的应用(2) 中缀算术表达式到后缀(逆波兰记法reverse polish notation)的转换及其计算 C++实现
- 中缀表达式转后缀表达式求值(栈的应用)