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.
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上有一道相同的題,但是運算符不僅包含"+"、"-",還包含了 "*" 和 "/",不過不用自己解析操作數了。
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
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 };