中缀表达式转逆波兰表达式,逆波兰表达式的计算
中缀表达式转后缀表达式:
1. 中缀表达式,是我们人可以识别的表达式形式;
2. 后缀表达式是计算机可以识别的表达式形式。
大体思路:
- 将中缀表达式的每一个符号存放在ArrayList a里面
- 新建一个栈stack s来存储中间符号,创建一个ArrayList b存放后缀表达式(为什么不用栈呢?因为要将存入的字符遍历,先进先出,用List更加方便)
- 扫描a:
- 如果是数字,直接放入b即可;
- 如果是符号:
- '(' : push到s中
- ')' : push栈s中的栈顶元素,依次存入b中,直到遇到'(',且这对括号可以被丢弃了
- 其他运算符:比较该运算符和s栈顶元素的优先级,若它的优先级高,则直接放入s中;若它的优先级<=栈顶元素的优先级,则将栈顶元素pop出来,存入b中,别忘了此时将该运算符继续与s栈顶元素比较
public static List<String> parseSuffixExpressionList(List<String> list) { //定义两个栈 Stack<String> s1 = new Stack<>(); //符号栈 //s2栈没有pop操作,需要逆序输出,如果用栈结构比较麻烦,所以可以用数组实现 //Stack<String> s2 = new Stack<>(); // 存储结果 ArrayList<String> s2 = new ArrayList<>(); //存储结果 for (String ele : list) { //如果是一个数,则加入s2 if (ele.matches("\\d+")) { s2.add(ele); } else if (ele.equals("(")) { s1.push(ele); } else if (ele.equals(")")) { //如果是右括号,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号未知,且这对括号呗丢弃 while (!s1.peek().equals("(")) { s2.add(s1.pop()); } //左括号被弹出(消除括号) s1.pop(); } else { //操作符的优先级 //当ele的优先级小于等于s1栈顶运算符,将s1栈顶的运算符弹出并加入到s2,再次将ele与新的栈顶运算符比较 while (s1.size() != 0 && Operation.getValue(ele) <= Operation.getValue(s1.peek())){ s2.add(s1.pop()); } s1.push(ele); } } //将s1中的剩余的符号依次弹出并加入到s2; while (!s1.empty()){ s2.add(s1.pop()); } return s2; }
那下面写如何计算逆波兰表达式吧
//完成对逆波兰表达式的运算 public static int calculate(List<String> list) { //创建栈 Stack<String> stack = new Stack<>(); //遍历list for (String s : list) { if (s.matches("\\d+")) { //匹配是多位数 stack.push(s); } else { //pop出两个数进行运算 int num2 = Integer.parseInt(stack.pop()); int num1 = Integer.parseInt(stack.pop()); int res = 0; //存放结果 if (s.equals("+")) { res = num1 + num2; } else if (s.equals("-")) { res = num1 - num2; } else if (s.equals("*")) { res = num1 * num2; } else if (s.equals("/")) { res = num1 / num2; } else { throw new RuntimeException("运算符有误"); } stack.push(res + ""); } } //最后留在stack中的数据是结果 return Integer.parseInt(stack.pop()); }

浙公网安备 33010602011771号