概念
- 前綴表達式(波蘭表達式)
運算符位于操作數(shù)前,右到左依次入棧
- 中綴表達式
從左到右依次入棧,一般轉(zhuǎn)為后綴表達式
- 后綴表達式(逆波蘭表達式)
運算符位于操作數(shù)后
中綴轉(zhuǎn)后綴(思路)
- 初始化倆個棧,運算符s1與存儲中間結(jié)果棧S2
- 左到右掃描中綴表達式
- 遇到操作數(shù),直接入S2
- 遇到運算符,比較與S1棧頂運算符優(yōu)先級比較
- 如果運算符棧為空,直接入棧
- 如果優(yōu)先級比S1棧頂優(yōu)先級高,直接入棧
- 否則將S1出棧到S2,再次跳轉(zhuǎn)到第四步,進行比較
- 遇到括號
- 左括號,直接入棧
- 有括號,依次彈出,并入S2,直到遇到左括號
- 重復(fù)Step 2~5 直到到達表達式最右端
- 將S1有依次彈出,并壓入S2
8.S2中的元素依次彈出,逆序就是后綴表達式
代碼實現(xiàn)
public class PolandExpression {
public static void main(String[] args) {
PolandExpression pe = new PolandExpression();
// List<String> mList = pe.middlePolandToList("(3+4)*5-6");
List<String> mList = pe.middlePolandToList("4*5-8+60+8/2");
System.out.println("中綴表達式 : " + mList);
List<String> aList = pe.middleToAffter(mList);
System.out.println("后綴表達式 : " + aList);
pe.calculation(aList);
}
public List<String> middleToAffter(List<String> mStr) {
List<String> aList = new ArrayList<>();
Stack<String> operStack = new Stack<>();
Stack<String> numStack = new Stack<>();
int currIndex = 0;
while (true) {
if (currIndex > mStr.size() - 1) {
break;
}
String curStr = mStr.get(currIndex);
if (strIsNum(curStr)) {
//數(shù)字直接入棧
numStack.push(curStr);
} else {
if ("(".equals(curStr)) {
operStack.push(curStr);
} else if (")".equals(curStr)) {
while (true) {
String top = operStack.pop();
if ("(".equals(top)) {
break;
} else {
numStack.push(top);
}
}
} else {
if (operStack.isEmpty()) {
//字符棧為空,直接入棧
operStack.push(curStr);
} else if (compareChar(curStr.charAt(0), operStack.peek().charAt(0))) {
//字符優(yōu)先級高于棧頂
operStack.push(curStr);
} else {
numStack.push(operStack.pop());
continue;
}
}
}
currIndex++;
}
while (true) {
if (operStack.isEmpty()) {
break;
} else {
numStack.push(operStack.pop());
}
}
while (true) {
if (numStack.isEmpty()) {
break;
} else {
aList.add(numStack.pop());
}
}
numStack.stream().forEach(str -> {
aList.add(str);
});
for (int i = 0; i < aList.size() / 2; i++) {
int size = aList.size();
String m = aList.get(i);
aList.set(i, aList.get(size - 1 - i));
aList.set(size - 1 - i, m);
}
return aList;
}
public boolean strIsNum(String str) {
return str.matches("\\d+");
}
/**
* 中綴表達式轉(zhuǎn)List
*/
public List<String> middlePolandToList(String str) {
List<String> list = new ArrayList<>();
String num = "";
for (int i = 0; i < str.length(); i++) {
char curChar = str.charAt(i);
if (!Character.isDigit(curChar)) {
list.add(Character.toString(curChar));
} else {
if (i == str.length() - 1) {
list.add(Character.toString(curChar));
} else if (Character.isDigit(str.charAt(i + 1))) {
num += curChar;
continue;
} else {
num += curChar;
list.add(num);
}
num = "";
}
}
return list;
}
public int cal(int num1, int num2, char oper) {
int resul = 0;
switch (oper) {
case '*':
resul = num1 * num2;
break;
case '-':
resul = num2 - num1;
break;
case '+':
resul = num1 + num2;
break;
case '/':
resul = num2 / num1;
break;
default:
break;
}
return resul;
}
/**
* 比較字符優(yōu)先級
*/
public boolean compareChar(char char1, char char2) {
if (char2 == '(' || char2 == ')') {
return true;
}
if (char1 == '*' || char1 == '/') {
if (char2 == '+' || char2 == '-') {
return true;
} else {
return false;
}
} else {
return false;
}
}
public void calculation(List<String> aList) {
int curIndex = 0;
Stack<String> stack = new Stack<>();
while (true) {
if (curIndex >= aList.size()) {
break;
}
String curStr = aList.get(curIndex);
if (strIsNum(curStr)) {
stack.push(curStr);
} else {
int num1 = Integer.parseInt(stack.pop());
int num2 = Integer.parseInt(stack.pop());
int cal = cal(num1, num2, curStr.charAt(0));
stack.push(cal + "");
}
curIndex++;
}
System.out.println(stack.pop());
}
}