Last active
August 29, 2015 14:24
-
-
Save junjiah/7dcd4835722b2c828b76 to your computer and use it in GitHub Desktop.
solved 'Basic Calculator II' on leetcode https://leetcode.com/problems/basic-calculator-ii/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Inspired from https://leetcode.com/discuss/42643/my-16-ms-no-stack-one-pass-short-c-solution | |
**/ | |
class Solution { | |
public: | |
// Regard expression series of *,/ as blocks, | |
// and try to 'inline' them as a single number. | |
int calculate(string s) { | |
// Expression result of current 'block'. | |
long curr_res = 0; | |
// Final result. | |
long res = 0; | |
// Regard the first number x as 0 + x. | |
char prev_op = '+'; | |
int i = 0; | |
const int len = s.length(); | |
while (i < len) { | |
if (s[i] == ' ') { | |
++i; | |
continue; | |
} | |
// If is a number, parse it. | |
if (isdigit(s[i])) { | |
int parsing_num = 0; | |
do { | |
parsing_num = parsing_num * 10 + (s[i] - '0'); | |
++i; | |
} while (isdigit(s[i])); | |
// 'Inline' operation result to current number. | |
switch (prev_op) { | |
case '*': | |
curr_res *= parsing_num; | |
break; | |
case '/': | |
curr_res /= parsing_num; | |
break; | |
case '+': | |
curr_res += parsing_num; | |
break; | |
case '-': | |
curr_res -= parsing_num; | |
} | |
} else { | |
char curr_op = s[i]; | |
if (curr_op == '+' || curr_op == '-') { | |
// Safe to accumulate the result of current block expression. | |
res += curr_res; | |
curr_res = 0; | |
} | |
prev_op = curr_op; | |
++i; | |
} | |
} | |
res += curr_res; | |
return res; | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public: | |
int calculate(string s) { | |
stack<long> operand_stack; | |
stack<char> op_stack; | |
long curr_num = 0; | |
int prev_op_precedence = -1; | |
for (char ch : s) { | |
if (ch == ' ') { | |
continue; | |
} | |
else if (ch >= '0' && ch <= '9') { | |
curr_num = curr_num * 10 + (ch - '0'); | |
continue; | |
} else { | |
// Number parsed. | |
operand_stack.push(curr_num); | |
curr_num = 0; | |
} | |
// Calculate precedence: '*' or '/' -> 1, | |
// '+' or '-' -> 0. | |
int op_precedence = ch == '*' || ch == '/'; | |
if (op_precedence <= prev_op_precedence) { | |
// Safe to calculate expressions in current stacks. | |
consumeStacks(operand_stack, op_stack, op_precedence); | |
} | |
op_stack.push(ch); | |
prev_op_precedence = op_precedence; | |
} | |
// Process the final number. | |
operand_stack.push(curr_num); | |
if (!op_stack.empty()) { | |
consumeStacks(operand_stack, op_stack, 0); | |
} | |
return operand_stack.top(); | |
} | |
private: | |
long eval(int operand1, int operand2, char op) { | |
long res; | |
switch (op) { | |
case '+': | |
res = operand2 + operand1; | |
break; | |
case '-': | |
res = operand2 - operand1; | |
break; | |
case '*': | |
res = operand2 * operand1; | |
break; | |
case '/': | |
res = operand2 / operand1; | |
} | |
return res; | |
} | |
template<class T> | |
inline static T getTopAndPop(stack<T> &st) { | |
T res = st.top(); | |
st.pop(); | |
return res; | |
} | |
void consumeStacks(stack<long> &operand_stack, | |
stack<char> &op_stack, int op_precedence) { | |
long operand1, operand2, op_stack_top_precedence; | |
char op; | |
do { | |
operand1 = getTopAndPop(operand_stack); | |
operand2 = getTopAndPop(operand_stack); | |
op = getTopAndPop(op_stack); | |
// Eval and push to the operand stack | |
operand_stack.push(eval(operand1, operand2, op)); | |
// Update prev precedence. | |
op_stack_top_precedence = | |
op_stack.empty() ? | |
-1 : (op_stack.top() == '*' || op_stack.top() == '/'); | |
} while (op_precedence <= op_stack_top_precedence); | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment