/**
* 波兰表达式;输入中序表达式-》导出后序表达式 -》根据后序表达式求出算式结果
*
* @author timmy1
*
*/
public class PolishExpression {
/**
* 中序转后序表达式规则:数字直接输入-运算符入栈,如果栈顶的运算符比要入栈的运算符优先级高的话,出栈-遇到右括号,则栈顶元素出栈,一直到左括号
*
* @param str
*/
private MyStack<String> expressionMiddleToAfter(String str) {
String[] strArr = str.split(" ");
MyStack<String> tempStack = new MyStack<>();// 中间转换的栈,进行入栈,出栈操作,
MyStack<String> resultStack = new MyStack<>();// 结果栈
for (int i = 0; i < strArr.length; i++) {
String data = strArr[i];
if (!isOperator(data)) {
// 不是运算符->数字-》直接输出-》入结果栈
resultStack.push(data);
continue;
} else {// 是运算符
// 1.如果转换栈为空,直接入栈
if (tempStack.size() == 0 || data.equals("(")) {
tempStack.push(data);
continue;
}else if (data.equals(")")) {// 中间栈不为空,且元素为由括号,则先判断中间栈是否有左括号-》有的话,需要出栈知道左括号出栈
int index = tempStack.search("(");
if (index == -1) {
// 没有左括号-》抛出异常
throw new IllegalArgumentException("栈中未找到左括号");
}
// 找到左括号,出栈
for (int j = tempStack.size() - 1; j > index; j--) {
// 获取栈顶元素->添加到结果栈
String peekData = tempStack.peek();
resultStack.push(peekData);
tempStack.pop();
}
// 将左括号出中间转换栈
tempStack.pop();
continue;
} else {
// 接下来的情况就是 + - * / 和(
if (isHigherPriorLevel(data, tempStack)) {
// 入栈元素运算符优先级高于中间栈栈顶元素优先级-》直接入栈中间栈
tempStack.push(data);
}else{
// 比栈顶优先级低的话,中间栈元素全部出栈,
while (tempStack.size() != 0) {
resultStack.push(tempStack.peek());
tempStack.pop();
}
tempStack.push(data);
}
}
}
}
while (tempStack.size() != 0) {
resultStack.push(tempStack.peek());
tempStack.pop();
}
return resultStack;
}
/**
* 当前运算符优先级是否高于中间转换栈的栈顶元素的优先级
*
* @param data
* @param tempStack
* @return
*/
private boolean isHigherPriorLevel(String data, MyStack<String> tempStack) {
if(tempStack.peek().equals("(")){
return true;
}
if (data.equals("*") || data.equals("/") && tempStack.peek().equals("+") || tempStack.peek().equals("-")) {
return true;
}
return false;
}
// 判断是否是运算符
private static boolean isOperator(String string) {
String[] operators = { "(", ")", "+", "-", "*", "/" };
for (int i = 0; i < operators.length; i++) {
if (string.equals(operators[i])) {
return true;
}
}
return false;
}
public static void main(String[] args) {
PolishExpression pExpression = new PolishExpression();
String str = "3 + ( 3 - 1 ) * 3 - 10 / 2";
PrintUtil.print("中序表达式为:" + str);
MyStack<String> resultStack = pExpression.expressionMiddleToAfter(str);
String[] resultStr = pExpression.printStackByBottom(resultStack);
int result = calculate(resultStr);
PrintUtil.print("最后结果为: "+result);
}
private static int calculate(String[] resultStr) {
MyStack<String> stack = new MyStack<>();
for(int i = 0;i<resultStr.length;i++){
String data = resultStr[i];
if(!isOperator(data)){
//数字入栈
stack.push(data);
}else{
//获取到运算符前面的两个元素,-》进行计算后-》结果入栈
String num1 = stack.peek();
stack.pop();
String num2 = stack.peek();
stack.pop();
int res = calc(num2,data,num1);
stack.push(res+"");
}
}
String retRes = stack.peek();
stack.pop();
return Integer.valueOf(retRes);
}
private static int calc(String num1, String data, String num2) {
int num11 = Integer.valueOf(num1);
int num22 = Integer.valueOf(num2);
if(data.equals("+")){
return num11+num22;
}else if(data.equals("-")){
return num11-num22;
}else if(data.equals("*")){
return num11*num22;
}else if(data.equals("/")){
return num11/num22;
}
return -1;
}
// 栈元素打印,从栈低开始打印
private String[] printStackByBottom(MyStack<String> stack) {
String[] str = new String[stack.size()];
int index = 0;
while (stack.size() != 0) {
str[index++] = stack.peek();
stack.pop();
}
// 反转
for (int i = 0; i < str.length / 2; i++) {
String temp = str[i];
str[i] = str[str.length - 1 - i];
str[str.length - 1 - i] = temp;
}
PrintUtil.printArray(str);
return str;
}
}
public class PrintUtil {
public static final int HORIZONTAL = 0;
public static void print(String str) {
System.out.println(str);
}
public static void printArray(int[] array, int confi) {
if (confi == HORIZONTAL) {
printHorizonal(array);
} else {
printArray(array);
}
}
private static void printHorizonal(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + ", ");
}
System.out.println("");
}
public static void printArray(int[] a) {
for (int i = 0; i < a.length; i++) {
print("元素" + (i + 1) + ":" + a[i]);
}
}
public static void printArray(String[] str) {
for (int i = 0; i < str.length; i++) {
System.out.print(str[i] + ", ");
}
System.out.println("");
}
}
结果打印:
中序表达式为:3 + ( 3 - 1 ) * 3 - 10 / 2
3, 3, 1, -, 3, *, +, 10, 2, /, -,
最后结果为: 4