思路图:
这里的s2栈我直接改为ArrayList因为最后是栈的结果的逆序,用ArrayList即可。ok上代码:
public class PolandNotation {
public static void main(String[] args) {
//定义中缀表达式
String expression = "1+((2.2+3.3)*4)-5";
List expressionArrayList = toInFixExpression(expression);
List suffixList = polandNotationArrayList(expressionArrayList);
//先定义一个逆波兰表达式
//String suffixExpression = "3 4 + 5 * 6 -";
//List suffixList = getListString(suffixExpression);
Double res = calLater(suffixList);
System.out.println("最终的结果是:"+res);
}
/**
* 中缀表达式转为ArrayList
* @param toExpression 中缀表达式字符串
* @return 中缀表达式的ArrayList
*/
public static List toInFixExpression(String toExpression){
List ls = new ArrayList();
int i =0;
String str;
char c;
do {
//如果c是一个非数字
if ((c = toExpression.charAt(i)) 57 && (c = toExpression.charAt(i)) != 46) {
ls.add(String.valueOf(c));
i++;
}else {
//是一个数字,就要考虑多位数的问题
str = "";
while (i = 48 && (c = toExpression.charAt(i)) <= 57 || i < toExpression.length() && (c = toExpression.charAt(i)) == 46) {
//拼接
str += c;
i++;
}
ls.add(str);
}
}while (i < toExpression.length());
return ls;
}
/**
* 逆波兰表达式转为数组
* @param suffixExpression 逆波兰表达式字符串
* @return 数组
*/
public static List getListString(String suffixExpression){
String[] split = suffixExpression.split(" ");
List lis = new ArrayList();
for (String ele: split){
lis.add(ele);
}
return lis;
}
/**
* 将中缀表达式转为逆波兰表达式
* @param ls 中缀表达式ArrayList
* @return 逆波兰表达式ArrayList
*/
public static List polandNotationArrayList(List ls){
//定义一个栈
Stack s1 = new Stack();
//可以用ArrayList即可
List s2 = new ArrayList();
for (String item: ls){
//如果是一个数就加入到s2
if (item.matches("\\d+") || item.matches("\\d+[.]{1}\\d+")){
s2.add(item);
}else if (item.equals("(")) {
s1.push(item);
}else if (item.equals(")")){
//如果是右括号,则依次弹出栈顶符号,并加入s2,直到遇到(为止
while (!s1.peek().equals("(")) {
s2.add(s1.pop());
}
//将(消除
s1.pop();
}else {
//当item的优先级小于或者等于s1的栈顶运算符时
while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)) {
s2.add(s1.pop());
}
//还需要将item压到s1中
s1.push(item);
}
}
while (s1.size() != 0){
s2.add(s1.pop());
}
return s2;
}
/**
* 计算逆波兰表达式
* @param list 需要计算的后缀表达式(逆波兰表达式)
* @return 结果
*/
public static Double calLater(List list){
//先创建一个数栈
Stack stack = new Stack();
for (String ch: list){
if (ch.matches("\\d+") || ch.matches("\\d+[.]{1}\\d+")){
stack.push(ch);
}else {
Double num1 = Double.parseDouble(stack.pop());
Double num2 = Double.parseDouble(stack.pop());
double res = 0;
if (ch.equals("+")){
res = num1 + num2;
}else if (ch.equals("*")){
res = num1 * num2;
}else if (ch.equals("-")){
res = num2 - num1;
}else if (ch.equals("/")){
res = num2 / num1;
}else {
throw new RuntimeException("运算符错误");
}
stack.push("" + res);
}
}
return Double.parseDouble(stack.pop());
}
}
//判断符号优先级的类
class Operation{
private static int ADD = 1;
private static int SUB = 1;
private static int MUL = 2;
private static int DIV = 2;
/**
* 判断符号优先级
* @param oper 符号
* @return 优先级数字
*/
public static int getValue(String oper){
int result = 0;
switch (oper){
case "+":
result = ADD;
break;
case "-":
result = SUB;
break;
case "*":
result = MUL;
break;
case "/":
result = DIV;
break;
default:
break;
}
return result;
}
}