一.后缀表达式
我们平常使用的是中缀表达式,而后缀表达式,即逆波兰表达式,在计算机看来是比较简单易懂的结构。因为计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序。
中缀表达式转为后缀表达式:
- 遇到数字直接输出,
- 遇到 ‘(’ 则直接入栈,
- 遇到 ‘)’ 则出栈直至找到 ‘(’ 并把它出栈,
- 遇到其余运算符:
当前运算符与栈顶运算符优先级比较:
- 高于:入栈
- 低于:出栈
- 等于:出栈栈顶运算符并入栈当前运算符
优先级:
/ = * > + = - > <
乘除相等大于加减大于括号
二.代码
package myMath;
import java.util.Stack;
public class Test {
public static void main(String[] args) throws Exception {
Test test = new Test();
String source = "1+2*(3-4)";
String str = test.toNewString(source);
System.out.println("中缀表达式: " + source);
System.out.println("后缀表达式: " + str);
System.out.println("计算结果: " + test.getResult(str));
}
// 中缀表达式转为后缀表达式
public String toNewString(String source) throws Exception {
StringBuilder sb = new StringBuilder();
Stack<Character> stack = new Stack<>();
for(int i = 0; i < source.length(); i++){
char chr = source.charAt(i);
if(chr >= '0' && chr <= '9'){
sb.append(chr);
continue;
}
if(chr == '('){
stack.push(chr);
continue;
}
if(chr == ')'){
while (stack.peek() != '('){
sb.append(stack.pop());
}
stack.pop();
continue;
}
if(stack.isEmpty()){
stack.push(chr);
continue;
}
char topChr = stack.peek();
int level = compareLeave(chr, topChr);
if(level == 0){
sb.append(stack.pop());
stack.push(chr);
}else if (level == 1){
stack.push(chr);
continue;
}else {
sb.append(stack.pop());
i--;
continue;
}
}
while (!stack.isEmpty()){
sb.append(stack.pop());
}
return sb.toString();
}
/**
* 优先级比较
* @param chr
* @param topChr
* @return
* 0:chr == topChr
* 1:chr > topChr
* -1:chr < topChr
*/
public int compareLeave(char chr, char topChr) throws Exception {
switch (chr){
case '+' :
case '-' :
if(topChr == '+' || topChr == '-') return 0;
else if (topChr == '*' || topChr == '/') return -1;
else if(topChr == '(') return 1;
break;
case '*':
case '/':
if(topChr == '+' || topChr == '-'|| topChr == '(') return 1;
else if(topChr == '*' || topChr == '/') return 0;
break;
default:
throw new Exception("比较失败");
}
return 0;
}
public double getResult(String str) throws Exception {
Stack<Character> cStack = new Stack<>();
Stack<Double> dStack = new Stack<>();
int i = 0;
for(; i < str.length(); i++){
char chr = str.charAt(i);
if(chr >= '0' && chr <= '9') dStack.push(Integer.parseInt(""+chr) / 1.0);
else break;
}
while (i<str.length()){
Double a = dStack.pop();
Double b = dStack.pop();
char c = str.charAt(i);
Double d = operate(b,a,c);
dStack.push(d);
i++;
}
return dStack.pop();
}
public double operate(double a, double b, char c) throws Exception {
switch (c){
case '+':
return a + b;
case '-':return a - b;
case '*':return a * b;
case '/':return a / b;
default:
throw new Exception("计算失败");
}
}
}