学习笔记-中缀表达式转逆波兰表达式(后缀表达式)

Talia ·
更新时间:2024-11-15
· 848 次阅读

中缀表达式转后缀表达式实现计算器(支持括号以及小数点不支持空白符)

思路图:
在这里插入图片描述
这里的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; } }
作者:Shine_QianMo



中缀表达式 逆波兰表达式 后缀表达式 学习笔记 学习

需要 登录 后方可回复, 如果你还没有账号请 注册新账号