[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 };

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM