数据结构006_逆波兰计算器分析和实现
前缀表达式也叫波兰表达式。后缀表达式也叫逆波兰表达式。
逆波兰表达式实现计算器:
package com.njcx.test3; import java.util.ArrayList; import java.util.List; import java.util.Stack; public class PolandNotation { /** * 逆波兰计算器 1.输入一个逆波兰表达式(后缀表达式),使用栈(stack),计算其结果 2.支持小括号和多位数 * * 从左到右扫描表达式,遇到数字,就把数字压入堆栈。 遇到运算符,弹出栈顶的两个数,用运算符对他们做相应的计算(次顶元素和栈顶元素),并将结果入栈。 * 重复上述步骤直到表达式最右端,最后运算得出的值即为表达式的结果。 */ public static void main(String[] args) { // 先定义一个逆波兰表达式 (3+4)*5-6 -> 3 4 + 5 * 6 - String suffixExpression = "3 4 + 5 * 6 -"; // 为了方便,逆波兰表达式中数字和符号用空格隔开 // 思路 // 1.先将suffixExpression放到arrayList中 // 2.将ArrayList传给一个方法,遍历ArrayList配合栈完成计算 List<String> rpnList = getListString(suffixExpression); System.out.println("rpnList = " + rpnList); int res = calculate(rpnList); System.out.println("计算结果是=" + res); } // 依次将一个逆波兰表达式的数据和运算符放入到ArrayList中,这样就不需要设置一个索引一个一个扫描这个表达式了 public static List<String> getListString(String suffixExpression) { // 将suffixExpression分割 String[] split = suffixExpression.split(" "); List<String> list = new ArrayList<String>(); for (String elem : split) { list.add(elem); } return list; } // 完成对逆波兰表达式的步骤 /** * 从左到右扫描表达式,遇到数字,就把数字压入堆栈。 遇到运算符,弹出栈顶的两个数, 用运算符对他们做相应的计算(次顶元素和栈顶元素),并将结果入栈。 * 重复上述步骤直到表达式最右端,最后运算得出的值即为表达式的结果。 */ public static int calculate(List<String> list) { // 创建栈,只需要一个栈即可 Stack<String> stack = new Stack<String>(); // 遍历list for (String item : list) { // 这里使用一个正则表达式来取到数 if (item.matches("\\d+")) { // 匹配的是多位数 // 入栈 stack.push(item); } else { // pop出两个数并运算再入栈 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()); } }