@administrators @contributors
question 770. Basic Calculator IV
my code did not pass, but the report is weird.

result on my machine is { "-50" }
my code is:
namespace {
struct Formatter {
bool operator()(const multiset<string>& a, const multiset<string>& b) const {
if (a.size() > b.size()) return true;
if (a.size() == b.size()) return a < b;
return false;
}
};
using Term = map<multiset<string>, int, Formatter>;
Term operator+(const Term& a, const Term& b) {
Term res(a);
for (auto& p : b) {
res[p.first] += p.second;
}
return res;
}
Term operator-(const Term& a, const Term& b) {
Term res(a);
for (auto& p : b) {
res[p.first] -= p.second;
}
return res;
}
Term operator*(const Term& a, const Term& b) {
Term res;
for (auto& pa : a) {
for (auto& pb : b) {
multiset<string> f(pa.first);
f.insert(pb.first.begin(), pb.first.end());
res[f] += pa.second * pb.second;
}
}
return res;
}
Term calc(const Term& a, const Term& b, char op) {
switch (op) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
default:
__builtin_unreachable();
}
}
struct Reader {
Reader(const string& str, const unordered_map<string, int>& table) : data(str), table(table) {
p = data.begin();
}
pair<Term, char> read() {
if (p == data.end()) return make_pair(Term(), 'E');
while (*p == ' ') ++p;
if (isalnum(*p)) {
string res;
while (isalnum(*p)) res.push_back(*p++);
if (isdigit(res.front())) return make_pair(Term{{{}, stol(res)}}, 'T');
else if (table.count(res)) return make_pair(Term{{{}, table.at(res)}}, 'T');
else return make_pair(Term{{{res}, 1}}, 'T');
} else {
return make_pair(Term(), *p++);
}
}
const string& data;
const unordered_map<string, int>& table;
string::const_iterator p;
};
}
class Solution {
public:
void reduce(stack<Term>& ts, stack<char>& os) {
Term t2 = move(ts.top());
ts.pop();
Term t1 = move(ts.top());
ts.pop();
char op = os.top();
os.pop();
ts.push(calc(t1, t2, op));
}
vector<string> basicCalculatorIV(const string& expression, const vector<string>& evalvars, const vector<int>& evalints) {
unordered_map<string, int> table;
for (int i = 0; i < (int)evalvars.size(); ++i) table.emplace(evalvars[i], evalints[i]);
stack<Term> ts;
stack<char> os;
Reader reader(expression, table);
while (true) {
auto r = reader.read();
switch (r.second) {
case '(':
os.push('(');
continue;
case ')':
while (os.top() != '(') reduce(ts, os);
os.pop();
continue;
case '+':
if (os.size() && os.top() != '(') reduce(ts, os);
os.push('+');
continue;
case '-':
if (os.size() && os.top() != '(') reduce(ts, os);
os.push('-');
continue;
case '*':
if (os.size() && os.top() == '*') reduce(ts, os);
os.push('*');
continue;
case 'T':
ts.push(move(r.first));
continue;
default:
while (os.size()) reduce(ts, os);
}
break;
}
Term ft = move(ts.top());
ts.pop();
vector<string> res;
for (auto& p : ft) {
if (p.second == 0) continue;
string s(to_string(p.second));
for (auto& f : p.first) {
s += "*" + f;
}
res.push_back(move(s));
}
return res;
}
};