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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
bool is_operator(char c) {
  string opes = "+-^*";
  REP(i, opes.size()) if (c == opes[i]) return true;
  return false;
}
string preprocessing(string s) {
  stringstream ss(s);
  string res;
  ss >> res;
  while (ss >> s) {
    char a = res[res.size() - 1];
    char b = s[0];
    if (isdigit(a) && isdigit(b))
      res += "*" + s;
    else
      res += s;
  }
  return res;
}
typedef map<char, int> Var;
Var mul(Var x, Var y) {
  FORIT(it, y) { x[it->first] += it->second; }
  return x;
}
struct Result {
  map<Var, int> value;
  int p;
  Result(map<Var, int> v, int p) : value(v), p(p) {}
};
Result expression(const string &s, int p);
Result term(const string &s, int p);
Result term_pow(const string &s, int p);
Result factor(const string &s, int p);
Result expression(const string &s, int p) {
  Result r = term(s, p);
  while (s[r.p] == '+' || s[r.p] == '-') {
    Result t = term(s, r.p + 1);
    FORIT(it, t.value) {
      if (s[r.p] == '+')
        r.value[it->first] += it->second;
      if (s[r.p] == '-')
        r.value[it->first] -= it->second;
    }
    r.p = t.p;
  }
  return r;
}
Result term(const string &s, int p) {
  Result r = factor(s, p);
  while (r.p < s.size() && (isdigit(s[r.p]) || isalpha(s[r.p]) ||
                            s[r.p] == '(' || s[r.p] == '*')) {
    if (s[r.p] == '*')
      r.p++;
    Result t = factor(s, r.p);
    map<Var, int> new_val;
    FORIT(it1, r.value) FORIT(it2, t.value) {
      new_val[mul(it1->first, it2->first)] += it1->second * it2->second;
    }
    r.value = new_val;
    r.p = t.p;
  }
  return r;
}
Result factor(const string &s, int p) {
  if (s[p] == '(') {
    Result r = expression(s, p + 1);
    assert(s[r.p] == ')');
    r.p++;
    return r;
  } else if (isdigit(s[p])) {
    int val = 0;
    while (isdigit(s[p])) {
      val = val * 10 + s[p++] - '0';
    }
    map<Var, int> expr;
    expr[Var()] = val;
    return Result(expr, p);
  } else if (isalpha(s[p])) {
    char c = s[p++];
    if (s[p] == '^') {
      p++;
      int val = 0;
      while (isdigit(s[p])) {
        val = val * 10 + s[p++] - '0';
      }
      map<Var, int> expr;
      Var v;
      v[c] = val;
      expr[v] = 1;
      return Result(expr, p);
    } else {
      map<Var, int> expr;
      Var v;
      v[c] = 1;
      expr[v] = 1;
      return Result(expr, p);
    }
    /*
  }else if(s[p] == '-'){
    Result r = factor(s, p + 1);
    FORIT(it, r.value){
      r.value[it->first] = -it->second;
    }
    return r;
  }else if(s[p] == '+'){
    Result r = factor(s, p + 1);
    return r;
    */
  } else {
    assert(false);
  }
}
string to_str(const Var &v) {
  string res;
  FORIT(it, v) {
    if (res != "")
      res += "*";
    stringstream ss;
    ss << it->first;
    if (it->second != 1) {
      ss << "^";
      ss << it->second;
    }
    res += ss.str();
  }
  return res;
}
void print(map<Var, int> &expr) {
  FORIT(it, expr) { printf("%+d%s", it->second, to_str(it->first).c_str()); }
  putchar('\\n');
}
bool equal(map<Var, int> e1, map<Var, int> e2) {
  FORIT(it, e1) {
    if (e1[it->first] != e2[it->first])
      return false;
  }
  FORIT(it, e2) {
    if (e1[it->first] != e2[it->first])
      return false;
  }
  return true;
}
int main() {
  string line;
  while (getline(cin, line) && line != ".") {
    // cout << line << endl;
    line = preprocessing(line);
    // cout << line << endl;
    Result r = expression(line, 0);
    map<Var, int> expr = r.value;
    // print(expr);
    while (getline(cin, line) && line != ".") {
      line = preprocessing(line);
      // cout << line << endl;
      Result r = expression(line, 0);
      map<Var, int> expr2 = r.value;
      // print(expr2);
      if (equal(expr, expr2))
        cout << "yes" << endl;
      else
        cout << "no" << endl;
    }
    cout << "." << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
bool is_operator(char c) {
  string opes = "+-^*";
  REP(i, opes.size()) if (c == opes[i]) return true;
  return false;
}
string preprocessing(string s) {
  stringstream ss(s);
  string res;
  ss >> res;
  while (ss >> s) {
    char a = res[res.size() - 1];
    char b = s[0];
    if (is_operator(a) || is_operator(b))
      res += s;
    else
      res += "*" + s;
  }
  REP(i, res.size() - 1) {
    if ((isalpha(res[i]) && isalpha(res[i + 1])) ||
        (isdigit(res[i]) && isalpha(res[i + 1])) ||
        (isalpha(res[i]) && isdigit(res[i + 1]))) {
      res.insert(++i, "*");
    }
  }
  return res;
}
typedef map<char, int> Var;
Var mul(Var x, Var y) {
  FORIT(it, y) { x[it->first] += it->second; }
  return x;
}
struct Result {
  map<Var, int> value;
  int p;
  Result(map<Var, int> v, int p) : value(v), p(p) {}
};
Result expression(const string &s, int p);
Result term(const string &s, int p);
Result term_pow(const string &s, int p);
Result factor(const string &s, int p);
Result expression(const string &s, int p) {
  Result r = term(s, p);
  while (s[r.p] == '+' || s[r.p] == '-') {
    Result t = term(s, r.p + 1);
    FORIT(it, t.value) {
      if (s[r.p] == '+')
        r.value[it->first] += it->second;
      if (s[r.p] == '-')
        r.value[it->first] -= it->second;
    }
    r.p = t.p;
  }
  return r;
}
Result term(const string &s, int p) {
  Result r = factor(s, p);
  while (s[r.p] == '*') {
    Result t = factor(s, r.p + 1);
    map<Var, int> new_val;
    FORIT(it1, r.value) FORIT(it2, t.value) {
      new_val[mul(it1->first, it2->first)] += it1->second * it2->second;
    }
    r.value = new_val;
    r.p = t.p;
  }
  return r;
}
Result factor(const string &s, int p) {
  if (s[p] == '(') {
    Result r = expression(s, p + 1);
    assert(s[r.p] == ')');
    r.p++;
    return r;
  } else if (isdigit(s[p])) {
    int val = 0;
    while (isdigit(s[p])) {
      val = val * 10 + s[p++] - '0';
    }
    map<Var, int> expr;
    expr[Var()] = val;
    return Result(expr, p);
  } else if (isalpha(s[p])) {
    char c = s[p++];
    if (s[p] == '^') {
      p++;
      int val = 0;
      while (isdigit(s[p])) {
        val = val * 10 + s[p++] - '0';
      }
      map<Var, int> expr;
      Var v;
      v[c] = val;
      expr[v] = 1;
      return Result(expr, p);
    } else {
      map<Var, int> expr;
      Var v;
      v[c] = 1;
      expr[v] = 1;
      return Result(expr, p);
    }
  } else if (s[p] == '-') {
    Result r = factor(s, p + 1);
    FORIT(it, r.value) { r.value[it->first] = -it->second; }
    return r;
  } else if (s[p] == '+') {
    Result r = factor(s, p + 1);
    return r;
  } else {
    assert(false);
  }
}
string to_str(const Var &v) {
  string res;
  FORIT(it, v) {
    if (res != "")
      res += "*";
    stringstream ss;
    ss << it->first;
    if (it->second != 1) {
      ss << "^";
      ss << it->second;
    }
    res += ss.str();
  }
  return res;
}
void print(map<Var, int> &expr) {
  FORIT(it, expr) { printf("%+d%s", it->second, to_str(it->first).c_str()); }
  putchar('\\n');
}
bool equal(map<Var, int> e1, map<Var, int> e2) {
  FORIT(it, e1) {
    if (e1[it->first] != e2[it->first])
      return false;
  }
  FORIT(it, e2) {
    if (e1[it->first] != e2[it->first])
      return false;
  }
  return true;
}
int main() {
  string line;
  while (getline(cin, line) && line != ".") {
    // cout << line << endl;
    line = preprocessing(line);
    Result r = expression(line, 0);
    map<Var, int> expr = r.value;
    // print(expr);
    while (getline(cin, line) && line != ".") {
      // cout << line << endl;
      line = preprocessing(line);
      Result r = expression(line, 0);
      map<Var, int> expr2 = r.value;
      // print(expr2);
      if (equal(expr, expr2))
        cout << "yes" << endl;
      else
        cout << "no" << endl;
    }
    cout << "." << endl;
  }
  return 0;
}