• [算法专题] 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

     

  • 相关阅读:
    汇编指令速查
    七种寻址方式(直接寻址方式)
    七种寻址方式(立即寻址、寄存器寻址)
    七种寻址方式(寄存器间接寻址方式)
    Indy IdHttp get Gb2312乱码的解决
    七种寻址方式(相对基址加变址寻址方式)
    七种寻址方式(寄存器相对寻址方式)
    【Note】2012.10.3
    算法04不重复打印排序数组中相加和为给定值的所有三元组
    算法03不重复打印排序数组中相加和为给定值的所有二元组
  • 原文地址:https://www.cnblogs.com/jianxinzhou/p/4783921.html
Copyright © 2020-2023  润新知