栈实现了一个逆波兰计算器,包含中序表达式到后缀表达式转换。
运行结果:
原始表达式:(3+4) * 5 - 16
后缀表达式:[3, 4, +, 5, *, 16, -]
算出来的结果为:19
代码:
package cn.agan.mystack;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
/**
* 逆波兰计算器: (3+4) * 5 - 6的后缀表达式为:3 4 + 5 * 6 -
* 1. 从左到右扫描,将3和4压入栈中
* 2. 遇到 + ,弹出3 4,计算值押入栈中
* 3. 5入栈,遇到*, 将栈中到两个数组弹出计算,值入栈
* 4. 6入栈;
* 5. 遇到 -, 弹出两个数计算得出结果,押入栈
*/
public class PolanNotation {
public static void main(String[] args) {
// "3 4 + 5 * 6 -"
String originExp = "(3+4) * 5 - 16";
System.out.println("原始表达式:"+originExp);
List<String> infixExp = toInfixExpressionList(originExp);
// System.out.println(infixExp);
List<String> tailExp = infixToTailExp(infixExp);
System.out.println("后缀表达式:" + tailExp);
// String suffixExpression = "3 4 + 5 * 6 -";
// List<String> rpnList = getListString(suffixExpression);
// System.out.println("" + rpnList);
int res = calPolanNotation(tailExp);
System.out.println("算出来的结果为:" + res);
}
//将逆波兰表达式,依次将数据和运算符放入到ArrayList中
public static List<String> getListString(String suffixExpression) {
//
String[] split = suffixExpression.split(" ");
List<String> list = new ArrayList<String>();
for (String ele : split) {
list.add(ele);
}
return list;
}
//完成逆波兰表达式到计算
public static int calPolanNotation(List<String> notation) {
ArrayStack2 arrayStack = new ArrayStack2(128);
int num1 = 0, num2 = 0, res = 0;
for (int i = 0; i < notation.size(); i++) {
if (isOperator(notation.get(i))) {
num2 = arrayStack.pop();
num1 = arrayStack.pop();
res = arrayStack.cal(num1, num2, notation.get(i).charAt(0));
arrayStack.push(res);
} else {
arrayStack.push(Integer.parseInt(notation.get(i)));
}
}
return arrayStack.pop();
}
public static boolean isOperator(String s) {
return "+".equals(s) || "-".equals(s) || "*".equals(s) || "/".equals(s);
}
//将中缀表达式转为List
public static List<String> toInfixExpressionList(String s) {
List<String> intList = new ArrayList<String>();
int i = 0;
String subStr; //对多位数拼接
char ch;
s = s.trim();
do {
ch = s.charAt(i);
if (ch == ' ') {
i++;
continue;
}
if(ch < 48 || ch > 57) {
//非数字
intList.add(""+ch);
i++;
} else {
subStr = "";
while (i < s.length() && (ch=s.charAt(i)) >= 48 && ch <= 57) {
subStr += ch;
i++;
}
intList.add(subStr);
}
} while (i < s.length());
return intList;
}
//中缀表达式转为后缀表达式 "1+((4-2)*5) - 6/3"
public static List<String> infixToTailExp(List<String> list) {
List<String> intList = new ArrayList<String>();
Stack<String> arrayStack2 = new Stack<String>();
for (String ele : list) {
if (ele.matches("\\d+")) {
intList.add(ele);
} else if (ele.equals("(")) {
arrayStack2.push(ele);
} else if (ele.equals(")")) {
while ( !arrayStack2.peek().equals("(")) {
intList.add(arrayStack2.pop());
}
arrayStack2.pop();
} else {
if (arrayStack2.size() != 0 ) {
int p1 = priority(ele);
int p2 = priority(arrayStack2.peek());
while (arrayStack2.size() != 0 && p1 <= p2) {
intList.add( arrayStack2.pop() );
}
}
arrayStack2.push(ele);
}
}
while (arrayStack2.size() != 0) {
intList.add(arrayStack2.pop());
}
return intList;
}
public static int priority(String opr) {
if (opr.equals("*" ) || opr.equals("/") ) {
return 4;
} else if (opr.equals("+") || opr.equals("-") ) {
return 3;
} else {
return -1; //暂时只支持+-*/
}
}
}