题目来源:leetCode OJ 逆波兰表达式
主要知识点:栈 Stack 一种遵循先进后出的特殊的线性表,只允许在固定的一端进行插入和删除元素。就像一个桶,最后放入桶中的东西会最先被取出来。
创建栈: Stack<泛型参数> 栈名 = new Stack<>();
核心操作:1 . 入栈 栈名.push(); // 用于将元素入栈,把元素添加到栈顶
2 . 出栈 栈名.pop(); // 将栈顶元素出栈,同时返回该元素,并且栈的大小减 1
3 . peek 栈名. peek(); // 查看栈顶元素,但不会移除该元素
逆波兰表达式 / 后缀表达式: 一种操作数在运算符前的表达式
eg: (1 + 2)x (3 + 4)
一般写作: ( 1 + 2 ) * ( 3 + 4 )
逆波兰写作: ( ( 1 2 + ) ( 3 4 + ) * )
解题思路:
1. 创建一个栈来存放数组中的元素
2. 遍历数组
3. 判断数组元素是否为数 是,将其入栈; 不是,出栈
4. 出栈记录操作数 按照运算符匹配运算法则 得出的结果入栈
5. 遍历完,栈中一定有一个元素,即最终的结果
eg:
字符数组 : 12+34+*
遍历 -> 1 是数 -> push(1) -> 2 是数 -> push(2) -> + 不是数 -> pop(2) pop(1) -> 1 + 2 = 3 -> push(3) -> 3 是数 -> push(3) -> 4 是数 -> push(4) -> + 不是数 -> pop(4) pop(3) -> 3 + 4 = 7 -> push(7) -> * 不是数 -> pop(7) pop(3) -> 3 * 7 = 21
代码实现:
private static boolean isNumber(String token){ // 如果 token 是运算符则返回false, 反之返回true if(token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/")){ return false; } return true; } // 逆波兰表达式 public int evalRPN(String[] tokens) { //1. 准备一个栈,放操作数 Stack<Integer> stack = new Stack<>(); //2. 遍历 tokens,取出每个元素 for(String token : tokens){ // 3. 判定 tokens 是否为数字 if(isNumber(token)){ // push stack.push(Integer.parseInt(token)); continue; } // 4. 判定token 是运算符 // 先出栈的是第二个操作数,后出栈的是第一个操作数 int num2 = stack.pop(); int num1 = stack.pop(); // 5. 判定当前的运算符是哪个,进行运算,把得到的结果入栈 if(token.equals("+")){ stack.push(num1 + num2); }else if(token.equals("-")){ stack.push(num1 - num2); }else if(token.equals("*")){ stack.push(num1 * num2); }else if(token.equals("/")){ stack.push(num1 / num2); } } // 最终整个表达式的结果就是栈里的唯一的一个元素 return stack.pop(); }
花开当折直须摘 青春最可爱 自己买花自己戴 爱恨多自在,只要人生不重来 何不放开怀 ———— David Tao