zoukankan      html  css  js  c++  java
  • 【LeetCode-栈】逆波兰表达式求值

    题目描述

    根据 逆波兰表示法,求表达式的值。

    有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
    说明:

    • 整数除法只保留整数部分。
    • 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

    示例:

    输入: ["2", "1", "+", "3", "*"]
    输出: 9
    解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
    
    输入: ["4", "13", "5", "/", "+"]
    输出: 6
    解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
    
    输入: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
    输出: 22
    解释: 
    该算式转化为常见的中缀算术表达式为:
      ((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
    

    逆波兰表达式:

    • 平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
    • 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
    • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
    • 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。

    思路

    题目对于逆波兰表达式的介绍很有用,特别是这一句适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。算法也就是这样做的:

    • 定义一个存储数字的栈:
      • 如果当前元素是数字,则入栈;
      • 如果当前元素是运算符,则出栈两个元素进行运算,将结果压入栈中;

    代码如下:

    class Solution {
    public:
        int evalRPN(vector<string>& tokens) {
            if(tokens.empty()) return 0;
    
            stack<int> nums;
            for(int i=0; i<tokens.size(); i++){
                if(tokens[i].size()>1) nums.push(stoi(tokens[i]));  // 长度大于 1,肯定是数字
                else{
                    if(isdigit(tokens[i][0])) nums.push(stoi(tokens[i]));
                    else{
                        int a = nums.top(); nums.pop();
                        int b = nums.top(); nums.pop();
                        if(tokens[i]=="+") nums.push(b+a);
                        else if(tokens[i]=="-") nums.push(b-a);  // 注意是 b-a,不是 a-b
                        else if(tokens[i]=="*") nums.push(b*a);
                        else if(tokens[i]=="/") nums.push(b/a);  // 注意是 b/a,不是 a/b
                    }
                }
            }
            return nums.top(); 
        }
    };
    

    需要注意的是,第一个出栈的元素为 a,第二个出栈的元素为 b,当前运算符为 opr,则操作是 b opr a,不是 a opr b。

  • 相关阅读:
    MySQL 复制
    MySQL 复制
    MySQL 复制
    MySQL 复制
    Setup Factory 读取安装包的配置文件
    [转]VC传递消息sendmessage
    JQuery.getJSON 没反应
    C#使用SendMessage传递字符串
    C# 注册表修改 立即生效 [转]
    c#开源项目[转]
  • 原文地址:https://www.cnblogs.com/flix/p/13301694.html
Copyright © 2011-2022 走看看