您的位置:首页 > 编程语言 > Java开发

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;
}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐