• [算法专题] stack


    1. Convert Expression to Reverse Polish Notation

    http://www.lintcode.com/en/problem/convert-expression-to-polish-notation/

    Given an expression string array, return the Polish notation of this expression. (remove the parentheses)

    Example

    For the expression [(5 − 6) * 7] (which represented by ["(", "5", "−", "6", ")", "*", "7"]), the corresponding polish notation is [* - 5 6 7] (which the return value should be ["*", "−", "5", "6", "7"]).

    Algorithm
    1. Scan the infix expression from left to right.
    2. If the scanned character is an operand, output it.
    3. Else,
    …..3.1 If the precedence of the scanned operator is greater than the precedence of the operator in the stack(or the stack is empty), push it.
    …..3.2 Else, Pop the operator from the stack until the precedence of the scanned operator is less-equal to the precedence of the operator residing on the top of the stack. Push the scanned operator to the stack.
    4. If the scanned character is an ‘(‘, push it to the stack.
    5. If the scanned character is an ‘)’, pop and output from the stack until an ‘(‘ is encountered.
    6. Repeat steps 2-6 until infix expression is scanned.
    7. Pop and output from the stack until it is not empty.

    代码如下:

    class Solution {
    public:
        /**
         * @param expression: A string array
         * @return: The Reverse Polish notation of this expression
         */
        vector<string> convertToRPN(vector<string> &exp) {
            vector<string> vec;
            stack<string> st;
            
            for (int ix = 0; ix != exp.size(); ix++) {
                if (isDigit(exp[ix])) {
                    vec.push_back(exp[ix]);
                } else if (exp[ix] == "(") {
                    st.push(exp[ix]);
                } else if (exp[ix] == ")") {
                    while (st.top() != "(") {
                        vec.push_back(st.top());
                        st.pop();
                    }
                    st.pop(); // pop "("
                } else {
                    while (!st.empty() && pri(exp[ix]) <= pri(st.top())) {
                        vec.push_back(st.top());
                        st.pop();
                    }
                    
                    st.push(exp[ix]);
                }
            }
            
            while (!st.empty()) {
                vec.push_back(st.top());
                st.pop();
            }
            
            return vec;
        }
        
    private:
        int isDigit(const string &s) {
            size_t len = s.size();
            string start(len, '0');
            string end(len, '9');
            return start <= s && s <= end;
        }
        
        int pri(const string &s) {
            if (s == "+" || s == "-") {
                return 1;
            } else if (s == "*" || s == "/") {
                return 2;
            }
            
            return -1;
        }
    };

    2. Expression Evaluation

    http://www.lintcode.com/en/problem/expression-evaluation/#

    Given an expression string array, return the final result of this expression

    Example

    For the expression 2*6-(23+7)/(1+2), input is

    [
      "2", "*", "6", "-", "(",
      "23", "+", "7", ")", "/",
      (", "1", "+", "2", ")"
    ],
    

    return 2

    Following is algorithm for evaluation postfix expressions.
    1) Create a stack to store operands (or values).
    2) Scan the given expression and do following for every scanned element.
    …..a) If the element is a number, push it into the stack
    …..b) If the element is a operator, pop operands for the operator from stack. Evaluate the operator and push the result back to the stack
    3) When the expression is ended, the number in the stack is the final answer

    Example:
    Let the given expression be “2 3 1 * + 9 -“. We scan all elements one by one.
    1) Scan ‘2’, it’s a number, so push it to stack. Stack contains ‘2’
    2) Scan ‘3’, again a number, push it to stack, stack now contains ‘2 3′ (from bottom to top)
    3) Scan ‘1’, again a number, push it to stack, stack now contains ‘2 3 1′
    4) Scan ‘*’, it’s an operator, pop two operands from stack, apply the * operator on operands, we get 3*1 which results in 3. We push the result ‘3’ to stack. Stack now becomes ‘2 3′.
    5) Scan ‘+’, it’s an operator, pop two operands from stack, apply the + operator on operands, we get 3 + 2 which results in 5. We push the result ‘5’ to stack. Stack now becomes ‘5’.
    6) Scan ‘9’, it’s a number, we push it to the stack. Stack now becomes ‘5 9′.
    7) Scan ‘-‘, it’s an operator, pop two operands from stack, apply the – operator on operands, we get 5 – 9 which results in -4. We push the result ‘-4′ to stack. Stack now becomes ‘-4′.
    8) There are no more elements to scan, we return the top element from stack (which is the only element left in stack).

    即遍历后缀表达式,遇到数字入栈,遇到operator弹栈计算,并将计算结果入栈,当遍历完后缀表达式后,栈顶元素即为返回值。代码如下:

    #include <stdlib.h>
    class Solution {
    public:
        /**
         * @param expression: a vector of strings;
         * @return: an integer
         */
        int evaluateExpression(vector<string> &exp) {
            if (exp.empty()) {
                return 0;
            }
            
            
            vector<string> post = convertToRPN(exp);
            stack<int> st;
            for (int ix = 0; ix != post.size(); ix++) {
                
                if (isDigit(post[ix])) {
                    st.push(atoi(post[ix].c_str()));
                } else {
    
                        int right = st.top(); st.pop();
                        int left = st.top(); st.pop();
                        int res = calculate(left, right, post[ix]);
                        st.push(res);
                    
                }
            }
            
            return st.top();
        }
        
    private:
        int calculate(int left, int right, const string &oper) {
         
            
            if (oper == "+") {
                return left + right;
            } else if (oper == "-") {
                return left - right;
            } else if (oper == "*") {
                return left * right;
            } else {
                return left / right;
            }
        }
        
        vector<string> convertToRPN(vector<string> &exp) {
            vector<string> vec;
            stack<string> st;
            
            for (int ix = 0; ix != exp.size(); ix++) {
                if (isDigit(exp[ix])) {
                    vec.push_back(exp[ix]);
                } else if (exp[ix] == "(") {
                    st.push(exp[ix]);
                } else if (exp[ix] == ")") {
                    while (st.top() != "(") {
                        vec.push_back(st.top());
                        st.pop();
                    }
                    st.pop(); // pop "("
                } else {
                    while (!st.empty() && pri(exp[ix]) <= pri(st.top())) {
                        vec.push_back(st.top());
                        st.pop();
                    }
                    
                    st.push(exp[ix]);
                }
            }
            
            while (!st.empty()) {
                vec.push_back(st.top());
                st.pop();
            }
            
            return vec;
        }
        
        int isDigit(const string &s) {
            size_t len = s.size();
            string start(len, '0');
            string end(len, '9');
            return start <= s && s <= end;
        }
        
        int pri(const string &s) {
            if (s == "+" || s == "-") {
                return 1;
            } else if (s == "*" || s == "/") {
                return 2;
            }
            
            return -1;
        }
    };

    3. Valid Parentheses

    http://www.lintcode.com/en/problem/valid-parentheses/#

    Given a string containing just the characters '(', ')', '{','}', '[' and ']', determine if the input string is valid.

    Example

    The brackets must close in the correct order, "()" and"()[]{}" are all valid but "(]" and "([)]" are not.

    class Solution {
    public:
        /**
         * @param s A string
         * @return whether the string is a valid parentheses
         */
        bool isValidParentheses(string& s) {
            stack<char> st;
            for (string::const_iterator itr = s.begin(); itr != s.end(); itr++) {
                
                if (st.empty()) {
                    st.push(*itr);
                } else if (consist(st.top(), *itr)) {
                    st.pop();
                } else {
                    st.push(*itr);
                }
            
            
            }
            
            return st.empty();
        }
        
    private:
        
        bool consist(const char left, const char right) {
            switch(left) {
                case '(' : 
                    return right == ')';
                case '[' :
                    return right == ']';
                case '{' :
                    return right == '}';
            }
        }
    };

    4

     

  • 相关阅读:
    dede模板留言提交错误时返回空白页处理方法
    Dedecms列表页通过函数调用当前文档tag的方法
    织梦dedecms如何让内容页显示不同的内容,但是每次更新都不变
    织梦DedeCMS网站服务器搬家详细教程
    让DEDECMS文章内容中链接新窗口打开的方法
    织梦dedecms中英文模版当前位置的修改方法
    织梦dedecms设置不同的搜索页模板教程
    简易版php文件上传_超详细详解
    nodejs 使用mongoose 操作mongodb
    记一个正则
  • 原文地址:https://www.cnblogs.com/jianxinzhou/p/4783921.html
Copyright © 2020-2023  润新知