概念
- 前缀表达式(波兰表达式)
运算符位于操作数前,右到左依次入栈
- 中缀表达式
从左到右依次入栈,一般转为后缀表达式
- 后缀表达式(逆波兰表达式)
运算符位于操作数后
中缀转后缀(思路)
- 初始化俩个栈,运算符s1与存储中间结果栈S2
- 左到右扫描中缀表达式
- 遇到操作数,直接入S2
- 遇到运算符,比较与S1栈顶运算符优先级比较
- 如果运算符栈为空,直接入栈
- 如果优先级比S1栈顶优先级高,直接入栈
- 否则将S1出栈到S2,再次跳转到第四步,进行比较
- 遇到括号
- 左括号,直接入栈
- 有括号,依次弹出,并入S2,直到遇到左括号
- 重复Step 2~5 直到到达表达式最右端
- 将S1有依次弹出,并压入S2
8.S2中的元素依次弹出,逆序就是后缀表达式
代码实现
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)) {
//数字直接入栈
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))) {
//字符优先级高于栈顶
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+");
}
/**
* 中缀表达式转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;
}
/**
* 比较字符优先级
*/
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());
}
}
网友评论