zoukankan      html  css  js  c++  java
  • 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.

    Some examples:

      ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9
      ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6

    分析:

    /*-----Reverse Polish Notation(逆波兰表达式),又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法,按此方法,每一运算符都置于其运算对象之后,故称为后缀表示。

    优势

    它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。其运算方式如下:
    如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。-----*/
     
    思路:利用堆栈来解决这道题。注意,我们还需要实现整数与字符串之间的相互转换。
    class Solution {  
    public:  
        int evalRPN(vector<string> &tokens) {  
            stack<int> cache;  
              
            for(int i = 0 ; i < tokens.size(); i++){  
                if(tokens[i] == "+" || tokens[i] == "-" || tokens[i] == "*" || tokens[i] == "/"){  
                    int num2 = cache.top();  
                    cache.pop();  
                    int num1 = cache.top();  
                    cache.pop();  
                    cache.push(calculate(num1, num2, tokens[i]));  
                }  
                else{  
                    cache.push(str2int(tokens[i]));  
                }  
            }  
              
            return cache.top();  
        }  
          
        int str2int(string s){  
            int result=0;  
            int base=1;  
            for(int i = s.size()-1;i>=0;i--){  
                if(s[i] == '-' && i == 0){  
                    result *= -1;  
                }  
                else if(s[i] >= '0' && s[i] <= '9'){  
                    result += base * (s[i] - '0');  
                    base *= 10;  
                }  
            }  
            return result;  
        }  
          
        int calculate(int num1, int num2, string op){  
            if(op == "+"){  
                return num1 + num2;  
            }  
            else if(op == "-"){  
                return num1 - num2;  
            }  
            else if(op == "*"){  
                return num1 * num2;  
            }else if(op == "/"){  
                return num1 / num2;  
            }  
        }  
    }; 
    

     其他方法:

    class Solution {
    public:
        int evalRPN(vector<string>& tokens) {
            stack<int> s;
            for (auto t : tokens) {                                         //自动类型推断
                if (t == "+" || t == "-" || t == "*" || t == "/") {
                    int y = s.top(); s.pop();
                    int x = s.top(); s.pop();
                    int z = 0;
                    switch (t.front()) {
                        case '+' :
                            z = x + y;
                            break;
                        case '-' :
                            z = x - y;
                            break;
                        case '*' :
                            z = x * y;
                            break;
                        case '/' :
                            z = x / y;
                            break;
                    }
                    s.push(z);
                } else {
                    s.push(stoi(t));     //字符串怎么转数值用函数 std::stoi()函数原型:
                                              //int stoi (const string& str, size_t* idx = 0, int base = 10); base 是进制                                                 
                }
            }
            return s.top();
        }
    };
    

      使用is_operator更简洁:

    class Solution {
    public:
        int evalRPN(vector<string>& tokens) {
        stack<int> stn;
        for(auto s:tokens) {
            if(s.size()>1 || isdigit(s[0])) stn.push(stoi(s));
            else {
                auto x2=stn.top(); stn.pop();
                auto x1=stn.top(); stn.pop();
                switch(s[0]) {
                    case '+': x1+=x2; break;
                    case '-': x1-=x2; break;
                    case '*': x1*=x2; break;
                    case '/': x1/=x2; break;
                }
                stn.push(x1);
            }
        }
        return stn.top();
    }
    };
    

      

  • 相关阅读:
    通过HttpListener实现简单的Http服务
    WCF心跳判断服务端及客户端是否掉线并实现重连接
    NHibernate初学六之关联多对多关系
    NHibernate初学五之关联一对多关系
    EXTJS 4.2 资料 跨域的问题
    EXTJS 4.2 资料 控件之Grid 那些事
    EXTJS 3.0 资料 控件之 GridPanel属性与方法大全
    EXTJS 3.0 资料 控件之 Toolbar 两行的用法
    EXTJS 3.0 资料 控件之 combo 用法
    EXTJS 4.2 资料 控件之 Store 用法
  • 原文地址:https://www.cnblogs.com/carsonzhu/p/4844909.html
Copyright © 2011-2022 走看看