Basic Calculator Solutions in C++
Number 224
Difficulty Hard
Acceptance 36.9%
Link LeetCode
Other languages Go
Solutions
C++ solution by haoel/leetcode
// Source : https://leetcode.com/problems/basic-calculator/// Author : Hao Chen// Date : 2015-06-12#include <stdlib.h>#include <ctype.h>#include <iostream>#include <string>#include <stack>#include <vector>using namespace std;/** Sorry, I cannot help using Design Pattern ;-)* (https://en.wikipedia.org/wiki/Interpreter_pattern)** Two Stack is cheap, design pattern is powerful! ;-)** But WTF, Memory Limit Exceeded!! Shit!!*/class Expression{public:virtual int interpret() = 0;virtual ~Expression() {};};class Number: public Expression{public:Number(string num) { this->number = atoi(num.c_str()); }~Number() { }int interpret() { return number; }private:int number;};class Plus : public Expression{public:Plus(Expression* left, Expression* right) :leftOperand(left), rightOperand(right) { }~Plus() { delete leftOperand; delete rightOperand; }int interpret() { return leftOperand->interpret() + rightOperand->interpret(); }private:Expression* leftOperand;Expression* rightOperand;};class Minus : public Expression{public:Minus(Expression* left, Expression* right) :leftOperand(left), rightOperand(right) { }~Minus() { delete leftOperand; delete rightOperand; }int interpret() { return leftOperand->interpret() - rightOperand->interpret(); }private:Expression* leftOperand;Expression* rightOperand;};class Multiply : public Expression{public:Multiply(Expression* left, Expression* right) :leftOperand(left), rightOperand(right) { }~Multiply() { delete leftOperand; delete rightOperand; }int interpret() { return leftOperand->interpret() * rightOperand->interpret(); }private:Expression* leftOperand;Expression* rightOperand;};class Divide : public Expression{public:Divide(Expression* left, Expression* right) :leftOperand(left), rightOperand(right) { }~Divide() { delete leftOperand; delete rightOperand; }int interpret() { return leftOperand->interpret() / rightOperand->interpret(); }private:Expression* leftOperand;Expression* rightOperand;};bool isOperator(const string &c) {return (c == "+" || c == "-" || c == "*" || c == "/" );}bool isOperator(const char &c) {return (c == '+' || c == '-' || c == '*' || c == '/');}class Evaluator : public Expression{private:Expression* syntaxTree;public:Evaluator(vector<string>& s){vector<Expression*> stack;for (unsigned int i=0; i < s.size(); i++) {if (isOperator(s[i])) {Expression* left = stack.back(); stack.pop_back();Expression* right = stack.back(); stack.pop_back();switch(s[i][0]) {case '+' :stack.push_back(new Plus(right, left)); break;case '-' :stack.push_back(new Minus(right, left)); break;case '*' :stack.push_back(new Multiply(right, left)); break;case '/' :stack.push_back(new Divide(right, left)); break;}}else{stack.push_back(new Number(s[i]));}}syntaxTree = stack.back();}~Evaluator() {delete syntaxTree;}int interpret() {return syntaxTree->interpret();}};vector<string> Parse(string& s){vector<string> exp;for(int i=0; i<s.size(); ){char c = s[i];string token;if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')' ) {exp.push_back(token+c);i++;continue;}if ( isdigit(c) ) {while( isdigit(s[i]) ) {token.push_back(s[i++]);}exp.push_back(token);continue;}i++;}return exp;}int Priority(const string &c) {if (c == "*" || c == "/") {return 2;} else if (c== "+" || c == "-") {return 1;} else {return 0;}}vector<string> Infix2RPN(vector<string>& infix) {vector<string> rpn;stack<string> s;for(int i = 0; i < infix.size(); i++) {if(isdigit(infix[i][0])) { //numberrpn.push_back(infix[i]);} else if (infix[i] == "(") {s.push(infix[i]);} else if (infix[i] == ")") {while(!s.empty() && s.top() != "(") {rpn.push_back(s.top());s.pop();}s.pop();}else if(isOperator(infix[i]) ){while(!s.empty() && Priority(s.top()) >= Priority(infix[i])) {rpn.push_back(s.top());s.pop();}s.push(infix[i]);}}while(!s.empty()) {rpn.push_back(s.top());s.pop();}return rpn;}//Design Pattern for RPN - Memory Limit Exceeded!!int calculate_RPN_design_pattern(string& s) {vector<string> exp = Parse(s);//for (int i=0; i<exp.size(); i++){// cout << exp[i] << " ";//}//cout << endl;exp = Infix2RPN(exp);for (int i=0; i<exp.size(); i++){cout << exp[i] << " ";}cout << endl;Evaluator sentence(exp);return sentence.interpret();}/** RPN - Reverse Polish Notation* see: https://en.wikipedia.org/wiki/Reverse_Polish_notation*///RPN evluation - Memory Limit Exceeded!!int calculate_RPN_evluation(string& s) {vector<string> exp = Parse(s);exp = Infix2RPN(exp);stack<int> ss;for(int i=0; i<exp.size(); i++) {if (isdigit(exp[i][0])) {ss.push(atoi(exp[i].c_str()));}if (exp[i]=="+" || exp[i]=="-") {int rhs = ss.top(); ss.pop();int lhs = ss.top(); ss.pop();if (exp[i]=="-") rhs = -rhs;ss.push(lhs + rhs);}}return ss.top();}//Two stack solution - quick & dirty solutioninline void calculate_two_stacks(stack<int>& num_stack, stack<char>& op_stack) {int lhs = num_stack.top(); num_stack.pop();int rhs = num_stack.top(); num_stack.pop();char op = op_stack.top(); op_stack.pop();if (op=='-') rhs = -rhs;num_stack.push(lhs + rhs);}int calculate_two_stacks(string& s) {stack<int> num_stack; //put the numberstack<char> op_stack; //put the operationsfor(int i = s.size() - 1; i >= 0; i--){if(s[i] == ')' || s[i] == '+' || s[i] == '-') {op_stack.push(s[i]);} else if(isdigit(s[i])){string num;num += s[i];while(isdigit(s[i-1])){num.insert(num.begin(), s[i-1]);i--;}num_stack.push(atoi(num.c_str()));} else if(s[i] == '('){while(op_stack.top() != ')') {calculate_two_stacks(num_stack, op_stack);}op_stack.pop();}}while(!op_stack.empty()){calculate_two_stacks(num_stack, op_stack);}return num_stack.top();}int calculate(string s) {return calculate_two_stacks(s);return calculate_RPN_evluation(s);return calculate_RPN_design_pattern(s);}int main(int argc, char** argv) {string s = " 15-(1+3)+(2+1) ";if (argc >1){s = argv[1];}cout << s << " = " << calculate(s) << endl;cout << "---------------" << endl;s = "(2+4)-(6+(1+5))";cout << s << " = " << calculate(s) << endl;}
C++ solution by liuyubobobo/Play-Leetcode
/// Source : https://leetcode.com/problems/basic-calculator/description//// Author : liuyubobobo/// Time : 2018-09-03#include <iostream>#include <vector>#include <cassert>using namespace std;/// Two Stacks/// Shunting-Yard Algorithms: https://en.wikipedia.org/wiki/Shunting-yard_algorithm////// Time Complexity: O(n)/// Space Complexity: O(n)class Solution {public:int calculate(string s) {vector<int> nums;vector<char> ops;for(int i = 0; i < s.size(); ){if(s[i] == '+' || s[i] == '-' || s[i] == '(')ops.push_back(s[i++]);else if(s[i] == ')'){assert(!ops.empty() && ops.back() == '(');ops.pop_back();i ++;cal(nums, ops);}else if(isdigit(s[i])){int num = s[i] - '0';int j;for(j = i + 1; j < s.size() && isdigit(s[j]); j ++)num = num * 10 + (s[j] - '0');i = j;nums.push_back(num);cal(nums, ops);}elsei ++;// Solution::print_vec(nums);// Solution::print_vec(ops);// cout << endl;}assert(nums.size() == 1);return nums.back();}private:void cal(vector<int>& nums, vector<char>& ops){if(!ops.empty() && (ops.back() == '+' || ops.back() == '-')){int second = nums.back();nums.pop_back();assert(!nums.empty());int first = nums.back();nums.pop_back();nums.push_back(ops.back() == '+' ? (first + second) : (first - second));ops.pop_back();}}template<typename T>static void print_vec(const vector<T>& vec){for(int i = 0; i < vec.size(); i ++)cout << vec[i] << " ";cout << endl;}};int main() {cout << Solution().calculate("1 + 1") << endl; // 2cout << Solution().calculate(" 2-1 + 2 ") << endl; // 3cout << Solution().calculate("(1+(4+5+2)-3)+(6+8)") << endl; // 23return 0;}