Problem p00684 (C++) — buggy submission, verdict: Runtime Error

#include <cmath>
#include <complex>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <vector>
using namespace std;

vector<string> to_postfix(string exp) {
  map<char, int> pd{{'+', 0}, {'-', 0}, {'*', 1}, {'/', 1}};
  stack<char> op;
  vector<string> pf;
  string num;
  for (auto c = exp.begin(); c != exp.end(); ++c) {
    if ((*c >= '0' && *c <= '9') || *c == 'i') {
      if (!(num == "0" && *c == '0')) {
        num.push_back(*c);
      }
    } else {
      if (!num.empty()) {
        if (num.front() == '0' && num.size() != 1) {
          num.erase(0, 1);
        }
        pf.push_back(num);
        num.clear();
      }
      switch (*c) {
      case '(':
        op.push('(');
        break;
      case ')':
        while (op.top() != '(') {
          pf.push_back(string().assign(1, op.top()));
          op.pop();
        }
        op.pop(); // pop '('
        break;
      default: // '+','-','*','/'
        while (!op.empty() && op.top() != '(' && pd[op.top()] >= pd[*c]) {
          pf.push_back(string().assign(1, op.top()));
          op.pop();
        }
        op.push(*c);
      }
    }
  }
  if (!num.empty()) {
    pf.push_back(num);
  }
  while (!op.empty()) {
    pf.push_back(string().assign(1, op.top()));
    op.pop();
  }
  return pf;
}

bool is_overflow(long long n) { return n > 10000ll || n < -10000ll; }

string calculate(vector<string> pf) {
  stack<complex<int>> ans; // stack of answers of calculation
  bool overflow = false;
  for (auto i = pf.begin(); i != pf.end(); ++i) {
    complex<int> first, second;
    if (i->back() == 'i') {
      if (i->size() - 1 > 10) {
        overflow = true;
        break;
      }
      long long image = *i == "i" ? 1l : stoll(i->substr(0, i->size() - 1));
      if (is_overflow(image)) {
        overflow = true;
        break;
      }
      ans.push(complex<int>(0, static_cast<int>(image)));
    } else if (i->back() >= '0' && i->back() <= '9') {
      if (i->size() > 10) {
        overflow = true;
        break;
      }
      long long real = stoll(*i);
      if (is_overflow(real)) {
        overflow = true;
        break;
      }
      ans.push(complex<int>(static_cast<int>(real), 0));
    } else {
      complex<int> second = ans.top();
      ans.pop();
      complex<int> first = ans.top();
      ans.pop();
      complex<int> res;
      switch (i->back()) {
      case '+':
        res = first + second;
        break;
      case '-':
        res = first - second;
        break;
      case '*':
        res = first * second;
        break;
      case '/':
        res = first / second;
      }
      if (is_overflow(res.real()) || is_overflow(res.imag())) {
        overflow = true;
        break;
      }
      ans.push(res);
    }
  }
  string result;
  if (overflow) {
    result = "overflow";
  } else {
    auto com = ans.top();
    if (com.real() == 0 && com.imag() == 0) {
      result = "0";
    } else if (com.real() == 0) {
      result = to_string(com.imag()) + "i";
    } else if (com.imag() == 0) {
      result = to_string(com.real());
    } else {
      result = to_string(com.real()) + (com.imag() < 0 ? "-" : "+") +
               to_string(abs(com.imag())) + "i";
    }
  }
  return result;
}

int main() {
  string exp;
  while (cin >> exp) {
    cout << calculate(to_postfix(exp)) << endl;
  }
}

Error: 0

Fixed submission:

#include <cmath>
#include <complex>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <vector>
using namespace std;

vector<string> to_postfix(string exp) {
  map<char, int> pd{{'+', 0}, {'-', 0}, {'*', 1}, {'/', 1}};
  stack<char> op;
  vector<string> pf;
  string num;
  for (auto c = exp.begin(); c != exp.end(); ++c) {
    if ((*c >= '0' && *c <= '9') || *c == 'i') {
      if (!(num == "0" && *c == '0')) {
        num.push_back(*c);
      }
    } else {
      if (!num.empty()) {
        if (num.front() == '0' && num.size() != 1) {
          num.erase(0, 1);
        }
        pf.push_back(num);
        num.clear();
      }
      switch (*c) {
      case '(':
        op.push('(');
        break;
      case ')':
        while (op.top() != '(') {
          pf.push_back(string().assign(1, op.top()));
          op.pop();
        }
        op.pop(); // pop '('
        break;
      default: // '+','-','*','/'
        while (!op.empty() && op.top() != '(' && pd[op.top()] >= pd[*c]) {
          pf.push_back(string().assign(1, op.top()));
          op.pop();
        }
        op.push(*c);
      }
    }
  }
  if (!num.empty()) {
    pf.push_back(num);
  }
  while (!op.empty()) {
    pf.push_back(string().assign(1, op.top()));
    op.pop();
  }
  return pf;
}

bool is_overflow(long long n) { return n > 10000ll || n < -10000ll; }

string calculate(vector<string> pf) {
  stack<complex<int>> ans; // stack of answers of calculation
  bool overflow = false;
  for (auto i = pf.begin(); i != pf.end(); ++i) {
    complex<int> first, second;
    if (i->back() == 'i') {
      long long image = *i == "i" ? 1l : stoll(i->substr(0, i->size() - 1));
      if (i->size() - 1 > 10 || is_overflow(image)) {
        overflow = true;
        break;
      }
      ans.push(complex<int>(0, static_cast<int>(image)));
    } else if (i->back() >= '0' && i->back() <= '9') {
      long long real = stoll(*i);
      if (i->size() > 10 || is_overflow(real)) {
        overflow = true;
        break;
      }
      ans.push(complex<int>(static_cast<int>(real), 0));
    } else {
      complex<int> second = ans.top();
      ans.pop();
      complex<int> first = ans.top();
      ans.pop();
      complex<int> res;
      switch (i->back()) {
      case '+':
        res = first + second;
        break;
      case '-':
        res = first - second;
        break;
      case '*':
        res = first * second;
        break;
      case '/':
        res = first / second;
      }
      if (is_overflow(res.real()) || is_overflow(res.imag())) {
        overflow = true;
        break;
      }
      ans.push(res);
    }
  }
  string result;
  if (overflow) {
    result = "overflow";
  } else {
    auto com = ans.top();
    if (com.real() == 0 && com.imag() == 0) {
      result = "0";
    } else if (com.real() == 0) {
      result = (com.imag() != 1 ? to_string(com.imag()) : "") + "i";
    } else if (com.imag() == 0) {
      result = to_string(com.real());
    } else {
      result = to_string(com.real()) + (com.imag() < 0 ? "-" : "+") +
               (com.imag() != 1 ? to_string(abs(com.imag())) : "") + "i";
    }
  }
  return result;
}

int main() {
  string exp;
  while (cin >> exp) {
    cout << calculate(to_postfix(exp)) << endl;
  }
}