棧實現了一個逆波蘭計算器,包含中序表達式到後綴表達式轉換。
運行結果:
原始表達式:(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; //暫時只支持+-*/
}
}
}