逆波兰表达式就是后缀表达式,比如正常表达式(也就是中缀表达式)是"300+5*((6- 3)-2)"的一个字符串,那么它的后缀表达式形式是[300, 5, 6, 3, -, 2, -, *, +](这里我就直接用集合的形式来表达)。用中缀表达式计算算式时,我们需要考虑优先级问题,如果没有小括号,问题就很简单,可这样功能较单一。而后缀表达式不需要考虑优先级问题,关键就放在了中缀表达式转换成后缀表达式,这里有笔者写的代码可供参考。
package com.stack;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class RPNCalculate {
public static void main(String[] args) {
String s = " 300+5*((6- 3) - 2)";
List<String> infixList = ToInfixExpressionList(s);
List<String> suffixList = parseSuffixExpressionList(infixList);
System.out.println(suffixList);
System.out.println(calculate(suffixList));
}
public static List<String> ToInfixExpressionList(String expression) {
expression = expression.replaceAll("\\s+", "");
int index = 0;
char c;
int len = expression.length();
String str;
List<String> list = new ArrayList<>();
do {
c = expression.charAt(index);
if ((c + "").matches("\\d+")) {
str = "";
while (index < len && ((c = expression.charAt(index)) + "").matches("\\d+")) {
str += c;
index++;
}
list.add(str);
} else {
list.add("" + c);
index++;
}
} while (index < len);
return list;
}
public static List<String> parseSuffixExpressionList(List<String> infixList) {
Stack<String> stack = new Stack<>();
List<String> list = new ArrayList<>();
for (String s : infixList) {
if (s.matches("\\d+"))
list.add(s);
else if (s.equals("("))
stack.push(s);
else if (s.equals(")")) {
while (!stack.peek().equals("("))
list.add(stack.pop());
stack.pop();
} else {
while (stack.size() != 0 && operation(s) <= operation(stack.peek())) {
list.add(stack.pop());
}
stack.push(s);
}
}
while (stack.size() != 0)
list.add(stack.pop());
return list;
}
public static float calculate(List<String> list){
Stack<Float> stack=new Stack<>();
for (String s : list) {
if (s.matches("\\d+"))
stack.push(Float.valueOf(s));
else {
float num2=stack.pop();
float num1=stack.pop();
switch (s){
case "+":
stack.push(num1+num2);
break;
case "-":
stack.push(num1-num2);
break;
case "*":
stack.push(num1*num2);
break;
case "/":
stack.push(num1/num2);
break;
default:
break;
}
}
}
return stack.pop();
}
public static int operation(String s) {
switch (s) {
case "+":
case "-":
return 1;
case "*":
case "/":
return 2;
case "(":
return 0;
default:
throw new RuntimeException(s + "不是运算符,请重新输入!");
}
}
}
万分感谢大家的阅读,有不足的地方希望大家可以指出。
|