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) { Stackstack = 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 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; } }}