【Java】【LeetCode】150. Evaluate Reverse Polish Notation

题目:

Evaluate the value of an arithmetic expression in Reverse Polish Notation.

Valid operators are +-*/. Each operand may be an integer or another expression.

Note:

  • Division between two integers should truncate toward zero.
  • The given RPN expression is always valid. That means the expression would always evaluate to a result and there won't be any divide by zero operation.

Example 1:

Input: ["2", "1", "+", "3", "*"]
Output: 9
Explanation: ((2 + 1) * 3) = 9

Example 2:

Input: ["4", "13", "5", "/", "+"]
Output: 6
Explanation: (4 + (13 / 5)) = 6

Example 3:

Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
Output: 22
Explanation: 
  ((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22

题解:
这道题,其实上过课的应该都知道,忘记是哪门课讲得了。。知道原理的话就比较容易写出来。下面引用一下什么是Reverse Polish
Notation:
“标准的表达式如"A+B",在数学上学名
叫中缀表达式(Infix Notation),原因是运算符号在两个运算对象的中间。相对应的还
有前缀表达式(Prefix 
Notation),如:"+ - A * B C D",转换成中缀表达式为:"A - B * C + D";后缀表达式(Postfix 
Notation),
比如前所述的中缀表达式转换为后缀表达式为:"A B C * - D +"。为了纪念波兰数学家鲁卡谢维奇(Jan Lukasiewicz),前缀表达式被称作波兰表达式,后缀表达式称为逆波兰表达式(Reverse Polish Notation)。
后缀表达式的优点是显而易见的,编译器在处理时候按照从左至右的顺序读取逆波兰表达式,遇到运算对象直接压入堆栈,遇到运算符就从堆栈提取后进的两个对象进行计算,这个过程正好符合了计算机计算的原理。
后缀表达式比前缀表达式更加易于转换,并且它的最左面一定为数字,这一点在实际编程的时候就会体会到它的好处了。
逆波兰表达式有一个更大的优点,就是拆括号,根据运算符的级别将中缀表达式转换成逆波兰表达式后,运算顺序就已经替代了运算符的级别,这样也避免了括号提高运算级别的特殊处理。
事实上,人的思维方式很容易固定~~!正如习惯了10进制,就对2,3,4,8,16等进制不知所措一样~~!人们习惯的运算方式是中缀表达式。而碰到前缀,后缀方式。。迷茫其实仅仅是一种表达式子的方式而已(不被你习惯的方式)我这里教你一种也许你老师都没跟你讲的简单转换方式一个中缀式到其他式子的转换方法~~这里我给出一个中缀表达式~a+b*c-(d+e)
第一步:按照运算符的优先级对所有的运算单位加括号~
        式子变成拉:((a+(b*c))-(d+e))
第二步:转换中缀与后缀表达式     
   后缀:把运算符号移动到对应的括号后面
        则变成拉:((a(bc)*)+(de)+)-
        把括号去掉:abc*+de+-  
后缀式子出现
发现没有,前缀式,后缀式是不需要用括号来进行优先级的确定的。
现在,你需要用计算机来实现这一过程,怎么样,是否有
兴趣一试呢?如果答案是肯定的话,Let‘s go!”

import java.util.Stack;

public class EvaluateReversePolishNotation {

    public static void main(String[] args) {
        /**
         * Example 1:
         * 
         * Input: ["2", "1", "+", "3", "*"] Output: 9 Explanation: ((2 + 1) * 3) = 9
         */
        String[] tokens1 = { "2", "1", "+", "3", "*" };
        System.out.println(evalRPN(tokens1));
        /**
         * Example 2:
         * 
         * Input: ["4", "13", "5", "/", "+"] Output: 6 Explanation: (4 + (13 / 5)) = 6
         */
        String[] tokens2 = { "4", "13", "5", "/", "+" };
        System.out.println(evalRPN(tokens2));
        /**
         * Example 3:
         * 
         * Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
         * Output: 22 Explanation: ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 = ((10 * (6 /
         * (12 * -11))) + 17) + 5 = ((10 * (6 / -132)) + 17) + 5 = ((10 * 0) + 17) + 5 =
         * (0 + 17) + 5 = 17 + 5 = 22
         */
        String[] tokens3 = { "10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+" };
        System.out.println(evalRPN(tokens3));
    }

    public static int evalRPN(String[] tokens) {
        if (tokens == null || tokens.length == 0) {
            return 0;
        }
        int result = 0;
        Stack<Integer> res = new Stack<Integer>();
        for (int i = 0; i < tokens.length; i++) {
            result = 0;
            if (tokens[i].equals("/") || tokens[i].equals("*") || tokens[i].equals("+") || tokens[i].equals("-")) {
                int b = res.pop();
                int a = res.pop();
                if (tokens[i].equals("/")) {
                    result += a / b;
                } else if (tokens[i].equals("+")) {
                    result += a + b;
                } else if (tokens[i].equals("-")) {
                    result += a - b;
                } else if (tokens[i].equals("*")) {
                    result += a * b;
                }
                res.push(result);
            } else {
                res.push(Integer.parseInt(tokens[i]));
            }
        }
        return res.pop();
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值