zoukankan      html  css  js  c++  java
  • [LeetCode] Basic Calculator & Basic Calculator II

    Basic Calculator

    Implement a basic calculator to evaluate a simple expression string.

    The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .

    You may assume that the given expression is always valid.

    Some examples:

    "1 + 1" = 2
    " 2-1 + 2 " = 3
    "(1+(4+5+2)-3)+(6+8)" = 23
    

     Note: Do not use the eval built-in library function.

    Basic Calculator II

    Implement a basic calculator to evaluate a simple expression string.

    The expression string contains only non-negative integers, +, -, *, and / operators. The integer division should truncate toward zero.

    You may assume that the given expression is always valid.

    Some examples:

    "3+2*2" = 7
    " 3/2 " = 1
    " 3+5 / 2 " = 5

    一个很详细的解释:http://www.geeksforgeeks.org/expression-evaluation/ 比这道题还难点

    思路就是两个stack,一个存数字一个存符号。如果遇到数字直接存到数字stack;如果遇到符号,有几种情况:

    1.当前符号比上一个符号优先级高,比如* 高于+,那么直接进栈

    2.当前符号低于上一个,那么就要把所有已经在stack里面优先于当前符号的全算完,再推进当前符号

    3.当前符号是“(”,直接push

    4.当前符号是“)”,就要把所有“(”以前的符号全部算完

    这道题只有“+”号与“-”号,不用判断符号的优先级。

    class Solution {
    private:
        bool isOK(char op1, char op2) {
            if (op1 == '*' || op1 == '/' || op2 == ')') return true;
            else return op2 == '+' || op2 == '-';
        }
        int calc(int a, int b, char op) {
            if (op == '+') return a + b;
            else if (op == '-') return a - b;
            else if (op == '*') return a * b;
            else return a / b;
        }
    public:
        int calculate(string s) {
            stack<int> stk_val;
            stack<char> stk_op;
            int res = 0, tmp;
            for (int i = 0; i <= s.length(); ++i) {
                //操作数
                if (i < s.length() && isdigit(s[i])) {
                    res = 0;
                    while (i < s.length() && isdigit(s[i])) {
                        res *= 10;
                        res += s[i++] - '0';
                    }
                    stk_val.push(res);
                }
                //运算符
                if (i == s.length() || s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/' || s[i] == ')') {
                    while (!stk_op.empty() && stk_op.top() != '(' && (i == s.length() || isOK(stk_op.top(), s[i]))) {
                        tmp = stk_val.top();
                        stk_val.pop();
                        stk_val.top() = calc(stk_val.top(), tmp, stk_op.top());
                        stk_op.pop();
                    }
                    if (i == s.length()) break;
                    else if (s[i] == ')') stk_op.pop();
                    else stk_op.push(s[i]);
                } else if (s[i] == '(') {
                    stk_op.push(s[i]);
                }
            }
            return stk_val.top();
        }
    };

    LintCode上有一道相同的题,但是运算符不仅包含"+"、"-",还包含了 "*" 和 "/",不过不用自己解析操作数了。

    Expression Evaluation

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

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

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

    return 2

    Note

    The expression contains only integer+-*/().

     1 class Solution {
     2 public:
     3     /**
     4      * @param expression: a vector of strings;
     5      * @return: an integer
     6      */
     7     int calulate(int a, int b, const string &op) {
     8         if (op == "+") return a + b;
     9         else if (op == "-") return a - b;
    10         else if (op == "*") return a * b;
    11         else return a / b;
    12     }
    13     bool isOK(const string &op1, const string &op2) {
    14         if (op1 == "*" || op1 == "/" || op2 == ")") return true;
    15         else return op2 == "+" || op2 == "-";
    16     }
    17     int evaluateExpression(vector<string> &expression) {
    18         // write your code here
    19         if (expression.empty()) return 0;
    20         stack<int> stk_val;
    21         stack<string> stk_op;
    22         for (int i = 0; i <= expression.size(); ++i) {
    23             if (i < expression.size() && isdigit(expression[i][0])) {
    24                 stk_val.push(atoi(expression[i].c_str()));
    25             } else if (i == expression.size() || expression[i] != "(") {
    26                 while (!stk_op.empty() && stk_op.top() != "(" 
    27                 && (i == expression.size() || isOK(stk_op.top(), expression[i]))) {
    28                     int tmp = stk_val.top();
    29                     stk_val.pop();
    30                     stk_val.top() = calulate(stk_val.top(), tmp, stk_op.top());
    31                     stk_op.pop();
    32                 }
    33                 if (i == expression.size()) break;
    34                 else if (expression[i] == ")") stk_op.pop();
    35                 else stk_op.push(expression[i]);
    36             } else {
    37                 stk_op.push(expression[i]);
    38             }
    39         }
    40         return stk_val.top();
    41     }
    42 };

    下面是求表达式树,同样的算法。

    Expression Tree Build

    The structure of Expression Tree is a binary tree to evaluate certain expressions. All leaves of the Expression Tree have an number string value. All non-leaves of the Expression Tree have an operator string value.

    Now, given an expression array, build the expression tree of this expression, return the root of this expression tree.

     

    For the expression (2*6-(23+7)/(1+2)) (which can be represented by ["2" "*" "6" "-" "(" "23" "+" "7" ")" "/" "(" "1" "+" "2" ")"]). The expression tree will be like

                     [ - ]
                 /          
            [ * ]              [ / ]
          /                /         
        [ 2 ]  [ 6 ]      [ + ]        [ + ]
                         /           /      
                       [ 23 ][ 7 ] [ 1 ]   [ 2 ] .
    

    After building the tree, you just need to return root node [-].

     1 /**
     2  * Definition of ExpressionTreeNode:
     3  * class ExpressionTreeNode {
     4  * public:
     5  *     string symbol;
     6  *     ExpressionTreeNode *left, *right;
     7  *     ExpressionTreeNode(string symbol) {
     8  *         this->symbol = symbol;
     9  *         this->left = this->right = NULL;
    10  *     }
    11  * }
    12  */
    13 
    14 class Solution {
    15 public:
    16     /**
    17      * @param expression: A string array
    18      * @return: The root of expression tree
    19      */
    20     bool isOK(const string &op1, const string &op2) {
    21         if (op1 == "*" || op1 == "/" || op2 == ")") return true;
    22         else return op2 == "+" || op2 == "-";
    23     }
    24     ExpressionTreeNode* build(vector<string> &expression) {
    25         // write your code here
    26         stack<ExpressionTreeNode*> stk_node;
    27         ExpressionTreeNode *left, *right, *tmp;
    28         stack<string> stk_op;
    29         stk_node.push(NULL);
    30         int n = expression.size();
    31         for (int i = 0; i <= n; ++i) {
    32             if (i < n && isdigit(expression[i][0])) {
    33                 tmp = new ExpressionTreeNode(expression[i]);
    34                 stk_node.push(tmp);
    35             } else if (i == n || expression[i] != "(") {
    36                 while (!stk_op.empty() && stk_op.top() != "(" && (i == n || isOK(stk_op.top(), expression[i]))) {
    37                     tmp = new ExpressionTreeNode(stk_op.top());
    38                     stk_op.pop();
    39                     right = stk_node.top(); stk_node.pop();
    40                     left = stk_node.top(); stk_node.pop();
    41                     tmp->left = left;
    42                     tmp->right = right;
    43                     stk_node.push(tmp);
    44                 }
    45                 if (i == n) break;
    46                 else if (expression[i] != ")") stk_op.push(expression[i]);
    47                 else stk_op.pop();
    48             } else {
    49                 stk_op.push("(");
    50             }
    51         }
    52         return stk_node.top();
    53     }
    54 };
  • 相关阅读:
    ajax原理及封装
    javascript 递归调用
    CSS的五种定位方式
    vue中iframe结合window.postMessage实现父子页面间的通信
    vue将文件流的形式的图形验证码转换成图片
    路由跳转打开新窗口,传递的参数不显示在地址栏
    js判断是否是ie浏览器、360浏览器兼容模式、QQ浏览器兼容模式、搜狗浏览器兼容模式,弹出提示使用别的浏览器打开
    vue项目中使用iframe嵌入静态页面,动态获取静态页面的高度赋值给iframe的高度
    vue项目中使用iview组件中的table插件实现表头文字居中,内容文字居左
    vue前端开发实现微信支付和支付宝支付
  • 原文地址:https://www.cnblogs.com/easonliu/p/4563780.html
Copyright © 2011-2022 走看看