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

#include <algorithm>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>

using namespace std;

typedef complex<int> P;

const int base = 10000;
bool isOverFlow;
P analyze(string s) {
  // cout<<s<<endl;
  if (s.size() == 1 && s[0] == 'i')
    return P(0, 1);
  if (s[0] >= '0' && s[0] <= '9') {
    bool ok = true;
    for (int i = 0; i < s.size(); i++)
      if (!(s[i] >= '0' && s[i] <= '9'))
        ok = false;
    if (ok) {
      int keta = 1;
      for (int j = 0; j < s.size(); j++) {
        if (s[j] != '0') {
          keta = max(keta, (int)s.size() - j);
          break;
        }
      }
      if (keta >= 6) {
        isOverFlow = true;
        return P();
      }
      int num = atoi(s.c_str());
      if (num > base) {
        isOverFlow = true;
        return P();
      }
      return P(num, 0);
    }
  } else if (s[0] == '-') {
    if (s.size() == 2 && s[1] == 'i')
      return P(0, -1);
    bool ok = true;
    for (int i = 1; i < s.size(); i++)
      if (!(s[i] >= '0' && s[i] <= '9'))
        ok = false;
    if (ok) {
      int keta = 1;
      for (int j = 1; j < s.size(); j++) {
        if (s[j] != '0') {
          keta = max(keta, (int)s.size() - j - 1);
          break;
        }
      }
      if (keta >= 6) {
        isOverFlow = true;
        return P();
      }
      int num = atoi(s.c_str());
      if (abs(num) > base) {
        isOverFlow = true;
        return P();
      }
      return P(num, 0);
    }
  }
  if (s[0] == '(') {
    int par = 1;
    bool ok = true;
    for (int i = 1; i < s.size() - 1; i++) {
      if (s[i] == '(')
        par++;
      else if (s[i] == ')')
        par--;
      if (par == 0)
        ok = false;
    }
    if (ok && par == 1) {
      return analyze(s.substr(1, s.size() - 2));
    }
  }
  int par = 0;
  for (int i = s.size() - 1; i >= 1; i--) {
    if (s[i] == ')')
      par++;
    else if (s[i] == '(')
      par--;
    else if (par == 0) {
      if (s[i] == '+' || s[i] == '-') {
        P p1 = analyze(s.substr(0, i));
        P p2 = analyze(s.substr(i + 1));
        if (abs(p1.real()) > base || abs(p2.real()) > base ||
            abs(p1.imag()) > base || abs(p2.imag()) > base) {
          isOverFlow = true;
          return P();
        }
        P p3;
        if (s[i] == '+')
          p3 = p1 + p2;
        else
          p3 = p1 - p2;
        if (abs(p3.real()) > base || abs(p3.imag()) > base) {
          isOverFlow = true;
          return P();
        }
        return p3;
      }
    }
  }
  par = 0;
  for (int i = s.size() - 1; i >= 0; i--) {
    if (s[i] == ')')
      par++;
    else if (s[i] == '(')
      par--;
    else if (par == 0) {
      if (s[i] == '*') {
        P p1 = analyze(s.substr(0, i));
        P p2 = analyze(s.substr(i + 1));
        if (abs(p1.real()) > base || abs(p2.real()) > base ||
            abs(p1.imag()) > base || abs(p2.imag()) > base) {
          isOverFlow = true;
          return P();
        }
        P p3 = p1 * p2;
        if (abs(p3.real()) > base || abs(p3.imag()) > base) {
          isOverFlow = true;
          return P();
        }
        return p3;
      }
    }
  }
  return P();
}

int main() {

  string s;
  while (getline(cin, s)) {
    isOverFlow = false;
    for (int i = 1; i < s.size(); i++) {
      if (s[i] == 'i' && s[i - 1] >= '0' && s[i - 1] <= '9')
        s = s.substr(0, i) + "*" + s.substr(i);
    }
    P res = analyze(s);
    if (isOverFlow)
      cout << "overflow" << endl;
    else {
      if (res.imag() == 0 && res.real() == 0)
        cout << 0 << endl;
      else {
        if (res.real() != 0)
          cout << res.real();
        if (res.imag() != 0) {
          if (res.imag() < 0)
            cout << res.imag() << "i";
          else {
            if (res.real() != 0)
              cout << "+";
            cout << res.imag();
            cout << "i";
          }
        }
        cout << endl;
      }
    }
  }

  return 0;
}

Error: -6
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 2) > this->size() (which is 1)


Fixed submission:

#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <stack>
#include <string>
#include <vector>

using namespace std;
bool no = false;

typedef long long ll;
typedef complex<ll> P;

P analysis(string str) {
  // ÊÉÎ·é
  bool isSurrounding = true;
  if (str[0] == '(' && str[str.size() - 1] == ')') {
    stack<char> s;
    s.push('(');
    for (int i = 1; i < str.size() - 1; i++) {
      if (str[i] == ')')
        s.pop();
      else if (str[i] == '(')
        s.push('(');
      if (s.size() == 0) {
        isSurrounding = false;
        break;
      }
    }
  } else
    isSurrounding = false;

  // ÍÜêÄ¢éê
  if (isSurrounding)
    return analysis(str.substr(1, str.size() - 2));

  isSurrounding = true;
  // }CiXÊ
  if (str.size() >= 3) {
    if (str[0] == '-' && str[1] == '(' && str[str.size() - 1] == ')') {
      stack<char> s;
      s.push('(');
      for (int i = 2; i < str.size() - 1; i++) {
        if (str[i] == ')')
          s.pop();
        else if (str[i] == '(')
          s.push('(');
        if (s.size() == 0) {
          isSurrounding = false;
          break;
        }
      }
    } else
      isSurrounding = false;
  }
  // ÍÜêÄ¢éê
  if (isSurrounding) {
    return -analysis(str.substr(2, str.size() - 3));
  }

  stack<char> ss;
  string bk = str;

  // ©Ç¤©
  // ¡f
  if (str == "i") {
    return P(0, 1);
  } else if ((str[0] >= '0' && str[0] <= '9') || str[0] == '-') {
    bool minus = false;
    if (str[0] == '-') {
      str = str.substr(1);
      minus = true;
    }
    bool isNum = true;
    bool isImagine = false;
    for (int i = 0; i < str.size(); i++) {
      if (i == str.size() - 1) {
        if (str[i] == 'i')
          isImagine = true;
        else if (!(str[i] >= '0' && str[i] <= '9')) {
          isNum = false;
          break;
        }
      } else {
        if (!(str[i] >= '0' && str[i] <= '9')) {
          isNum = false;
          break;
        }
      }
    }
    if (isNum) {
      if (!isImagine) {
        int idx = str.size() - 1;
        // æªÌ[ÌÊuð©Â¯é
        for (int i = 0; i < str.size(); i++) {
          if (str[i] != '0') {
            idx = i;
            break;
          }
        }
        // overflowµÄ¢È¢ê
        if (str.size() - idx <= 4 ||
            (str.size() - idx == 5 && abs(atoi(str.c_str())) == 10000)) {
          ll res = atoi(str.substr(idx).c_str());
          P p;
          if (!minus)
            p = P(res, 0);
          else
            p = P(-res, 0);
          return p;
        } else {
          no = true;
          return P();
        }
      } else {
        if (str == "i") {
          if (!minus)
            return P(0, 1);
          else
            return P(0, -1);
          // if(!minus)
          //	return P(0,1);
          // else
          //	return P(0,-1);
        }
        str = str.substr(0, str.size() - 1);
        int idx = str.size() - 1;
        // æªÌ[ÌÊuð©Â¯é
        for (int i = 0; i < str.size(); i++) {
          if (str[i] != '0') {
            idx = i;
            break;
          }
        }
        // overflowµÄ¢È¢ê
        if (str.size() - idx <= 4 ||
            (str.size() - idx == 5 && abs(atoi(str.c_str())) == 10000)) {
          ll res = atoi(str.substr(idx).c_str());
          P p;
          if (res == 0) {
            if (!minus)
              p = P(0, 1);
            else
              p = P(0, -1);
          } else {
            if (!minus)
              p = P(0, res);
            else
              p = P(0, -res);
          }
          return p;
        } else {
          no = true;
          return P();
        }
      }
    }
  }
  str = bk;
  // ZqðTõ(+ or -)
  for (int i = str.size() - 1; i >= 0; i--) {
    if (str[i] == '+' && ss.size() == 0) {
      P p1 = analysis(str.substr(0, i));
      P p2 = analysis(str.substr(i + 1));
      P res = p1 + p2;
      if (p1.real() > 10000 || p1.imag() > 10000 || p1.real() < -10000 ||
          p1.imag() < -10000) {
        no = true;
        return P();
      } else if (p2.real() > 10000 || p2.imag() > 10000 || p2.real() < -10000 ||
                 p2.imag() < -10000) {
        no = true;
        return P();
      } else if (res.real() > 10000 || res.imag() > 10000 ||
                 res.real() < -10000 || res.imag() < -10000) {
        no = true;
        return P();
      } else
        return res;
    } else if (str[i] == '(')
      ss.pop();
    else if (str[i] == ')')
      ss.push(')');
  }
  for (int i = str.size() - 1; i >= 0; i--) {
    if (i != 0 && str[i] == '-' && ss.size() == 0) {
      P p1 = analysis(str.substr(0, i));
      P p2 = analysis(str.substr(i + 1));
      P res = p1 - p2;
      if (p1.real() > 10000 || p1.imag() > 10000 || p1.real() < -10000 ||
          p1.imag() < -10000) {
        no = true;
        return P();
      } else if (p2.real() > 10000 || p2.imag() > 10000 || p2.real() < -10000 ||
                 p2.imag() < -10000) {
        no = true;
        return P();
      } else if (res.real() > 10000 || res.imag() > 10000 ||
                 res.real() < -10000 || res.imag() < -10000) {
        no = true;
        return P();
      } else
        return res;
    } else if (str[i] == '(')
      ss.pop();
    else if (str[i] == ')')
      ss.push(')');
  }

  // ZqðTõ(/ or *)
  for (int i = str.size() - 1; i >= 0; i--) {
    if (str[i] == '*' && ss.size() == 0) {
      P res = analysis(str.substr(0, i)) * analysis(str.substr(i + 1));
      // if(res.real()>10000||res.imag()>10000||res.real()<-10000||res.imag()<-10000){
      //	no=true;
      //	return P();
      // }
      // else
      return res;
    } else if (str[i] == '(')
      ss.pop();
    else if (str[i] == ')')
      ss.push(')');
  }
}

int main() {

  string str;
  while (cin >> str) {
    no = false;
    P p = analysis(str);
    if (p.real() > 10000 || p.imag() > 10000 || p.real() < -10000 ||
        p.imag() < -10000)
      no = true;
    if (no)
      cout << "overflow" << endl;
    else {
      bool ff = false;
      if (p.real() != 0) {
        ff = true;
        cout << p.real();
      }
      if (p.imag() != 0) {
        if (ff) {
          if (p.imag() == -1)
            cout << "-i";
          else if (p.imag() != 1)
            if (p.imag() < 0) {
              cout << p.imag() << "i";
            } else
              cout << "+" << p.imag() << "i";
          else
            cout << "+"
                 << "i";
        } else {
          if (p.imag() == -1)
            cout << "-i";
          else if (p.imag() != 1)
            cout << p.imag() << "i";
          else
            cout << "i";
        }
        ff = true;
      }
      if (!ff)
        cout << 0 << endl;
      else
        cout << endl;
    }
  }

  return 0;
}