前缀表达式(波兰表达式)
- 前缀表达式的运算符位于操作数之前;例:(3+4)*5-6 前缀表达式为 - * + 3 4 5 6
- 从右至左扫描,遇到数字压入数字栈,遇到运算符号时,出栈两个数,将运算结果入栈,直到扫描到算式的最左面
- 先出栈的数对后出栈的数进行运算
后缀表达式(逆波兰表达式)
- 从左至右扫描,遇到数字压入数字栈,遇到运算符号,弹出两个数字,进行运算,直到扫描到最右端。
- 后出栈的数对先出栈的数进行运算
中缀表达式转后缀表达式
转换步骤
- 定义两个栈,运算符栈、数字栈
- 从左至右扫描中缀表达式
- 当扫描到数字的时候最直接入数字栈
- 当运算符栈为空或为左括号‘(’时,扫描到运算符号,直接入符号栈
- 当符号栈不为空,如果优先级比栈顶符号高,则直接入符号栈;如果优先级小于等于栈顶符号,将符号栈栈顶符号出栈,将栈顶符号压入数字栈,再将当前符号压入符号栈。
- 当扫描到左括号‘(’,则直接压入符号栈
- 当扫描到右括号‘)’,则一次弹出符号栈中的符号,并以此入数字栈,直到栈顶符号位左括号,将这对括号丢弃。
- 当中缀表达式全部扫描完成,将符号栈剩下的符号一次压入数字栈中
- 结果为数字栈一次出栈的逆序。
代码展示:
class Postfix {
public String start(String Infix) {
int index = 0;
String keepnum = "";
Stack operStack = new Stack();
ArrayList numList = new ArrayList();
Postfix p = new Postfix();
while (true) {
char ch = Infix.substring(index, index + 1).charAt(0);
if (ch >= 48 && ch <= 57) {
keepnum += ch;
if (Infix.substring(index + 1, index + 2).charAt(0) <= 48 || Infix.substring(index + 1, index + 2).charAt(0) >= 57) {
numList.add(keepnum);
keepnum = "";
}
} else if (ch == '=') {
break;
} else {
if (operStack.isEmpty() || ch == '(') {
operStack.push(ch);
} else {
if (ch == ')') {
while (true) {
if ((char) operStack.peek() == '(') {
operStack.pop();
break;
}
numList.add(operStack.pop());
}
} else if (p.classifyOperation(ch) > p.classifyOperation((char) operStack.peek())) {
operStack.push(ch);
} else if (p.classifyOperation(ch) <= p.classifyOperation((char) operStack.peek())) {
numList.add(operStack.pop());
if (p.classifyOperation(ch) <= p.classifyOperation((char) operStack.peek()) && operStack.peek() != null) {
numList.add(operStack.pop());
}
}
}
}
index++;
}
while (!operStack.isEmpty()) {
numList.add(operStack.pop());
}
return numList.toString();
}
public int classifyOperation(char ch) {
if (ch == '+' || ch == '-') {
return 1;
} else if (ch == '*' || ch == '/') {
return 2;
} else if (ch == '(') {
return 0;
} else if (ch == ')') {
return 3;
} else {
return -1;
}
}
}