import java.util.ArrayList; import java.util.List; import java.util.Stack; public class PolandNotation { public static void main(String[] args) { //中缀表达式转后缀功能 //1. 1+((2+3)*4)-5 => 1 2 3 + 4 * + 5 - //2. 为方便操作将str转list //3. 将转换后的list转换成后缀表达式 String expression = "1+((2+3)*4)-5"; List<String> infixExpressionList = toInfixExpressionList(expression); // System.out.println(infixExpressionList); List<String> suffixExpressionList = parseSuffixExpressionList(infixExpressionList); System.out.println(suffixExpressionList); System.out.println(calculate(suffixExpressionList)); //先定义逆波兰表达式 //(30+4)*5-6 => 30 4 + 5 * 6 - //4*5-8+60+8/2 => 4 5 * 8 - 6 + 8 2 / + //985-728÷26×35 => 985 728 26 / 35 * - String suffixExpression = "985 728 26 / 35 * -"; //1. 先将 suffixExpression 放入 ArrayList //2. 将 ArrayList 传递给一个方法 配合栈完成计算 // List<String> rpnList = getListString(suffixExpression); // System.out.println("rpnList=" + rpnList); // int res = calculate(rpnList); // System.out.println(res); } //中缀表达式转后缀表达式 public static List<String> toInfixExpressionList(String s) { List<String> ls = new ArrayList<String>(); int i = 0;//用于遍历字符串 String str;//多位数拼接 char c;//遍历一个字符就放入到c do { if ((c = s.charAt(i)) < 48 || (c = s.charAt(i)) > 57) { ls.add("" + c); i++; } else { str = "";//先将str 置成"" while (i < s.length() && (c = s.charAt(i)) >= 48 && (c = s.charAt(i)) <= 57) { str += c; i++; } ls.add(str); } } while (i < s.length()); return ls; } public static List<String> parseSuffixExpressionList(List<String> ls) { Stack<String> s1 = new Stack<String>();//符号栈 List<String> s2 = new ArrayList<String>();//结果集合 for (String item : ls) { //如果是数 if (item.matches("\\d+")) { s2.add(item); } else if (item.equals("(")) { s1.push(item); } else if (item.equals(")")) { //依次弹出s1栈顶的运算符 加入s2 直到遇到左括号 这是一对括号丢弃 while (!s1.peek().equals("(")) { s2.add(s1.pop()); } s1.pop();//消除一对括号 } else { //当运算符小于栈顶运算符 将s1栈顶的运算符弹出并加入到s2中 然后继续比较直到大于栈顶运算符(peek()查看不取出) while (s1.size() != 0 && Operation.getValue(s1.peek()) >= Operation.getValue(item)) { s2.add(s1.pop()); } s1.push(item);//继续入栈操作 } } //将s1剩余的运算符依次弹出加入s2 while (s1.size() != 0) { s2.add(s1.pop()); } return s2; } public static List<String> getListString(String suffixExpression) { String[] split = suffixExpression.split(" "); ArrayList<String> list = new ArrayList<>(); for (String ele : split) { list.add(ele); } return list; } /** * 1.从左至右扫描 是数压入栈 * 2.遇到运算符 弹出栈顶的两个数字 计算 结果入栈 * 3.压入下一个数 * 4.遇到下一个运算符 弹出栈顶两个数(2的结果和3的数)计算入栈 * 5.压入下一个数 * 6.遇到下一个运算符 弹出栈顶两个数(4的结果和5的数)得出最后结果 * * @param ls 字符集合 * @return */ public static int calculate(List<String> ls) { Stack<String> stack = new Stack<String>(); for (String item : ls) { if (item.matches("\\d+")) { stack.push(item); } else { int num2 = Integer.parseInt(stack.pop()); int num1 = Integer.parseInt(stack.pop()); int res = 0; if (item.equals("+")) { res = num1 + num2; } else if (item.equals("-")) { res = num1 - num2; } else if (item.equals("*")) { res = num1 * num2; } else if (item.equals("/")) { res = num1 / num2; } else { throw new RuntimeException("运算符错误"); } stack.push("" + res); } } return Integer.parseInt(stack.pop()); } } //可以返回一个运算符对应的优先级 class Operation { private static int ADD = 1; private static int SUB = 1; private static int MUL = 2; private static int DIV = 2; public static int getValue(String operation) { int result = 0; switch (operation) { case "+": result = ADD; break; case "-": result = SUB; break; case "*": result = MUL; break; case "/": result = DIV; break; case "(": break; default: System.out.println("不支持该运算符"); break; } return result; } }
原文:https://www.cnblogs.com/bingbug/p/12083782.html