#include #include #include #include #include #include #include struct Token { std::variant token; explicit Token(char c) : token(c) {} explicit Token(int x) : token(x) {} [[nodiscard]] bool is_operator() const { return std::holds_alternative(token); } [[nodiscard]] char get_operator() const { if (!is_operator()) { throw std::invalid_argument("Not an operator"); } return std::get(token); } [[nodiscard]] int get_number() const { if (is_operator()) { throw std::invalid_argument("Is an operator"); } return std::get(token); } bool operator==(char c) const { if (!is_operator()) { return false; } return get_operator() == c; } bool operator==(int x) const { if (is_operator()) { return false; } return get_number() == x; } template bool operator!=(T x) { return !(*this == x); } }; using Expression = std::vector; Expression parse_string(const std::string& str) { Expression expression; std::string temp_token; for (char c : str) { if (!(c > '0' && c < '9')) { if (!temp_token.empty()) { expression.emplace_back(std::stoi(temp_token)); temp_token.clear(); } expression.emplace_back(c); } else { temp_token += c; } } if (!temp_token.empty()) { expression.emplace_back(std::stoi(temp_token)); } return expression; } void calculate_chunk(std::stack& undealt_tokens, std::stack& ready_tokens) { while (!undealt_tokens.empty() && undealt_tokens.top() != '(') { ready_tokens.push(undealt_tokens.top()); undealt_tokens.pop(); } int temp_result = ready_tokens.top().get_number(); ready_tokens.pop(); while (!ready_tokens.empty()) { char op = ready_tokens.top().get_operator(); ready_tokens.pop(); if (op == '+') { temp_result += ready_tokens.top().get_number(); } else if (op == '-') { temp_result -= ready_tokens.top().get_number(); } else { throw std::logic_error("Unexpected operator token in chunk."); } ready_tokens.pop(); } if (!undealt_tokens.empty()) { undealt_tokens.pop(); } undealt_tokens.emplace(temp_result); } int calculate(const Expression& expression) { // 策略: // 遇到 * / 直接算(本质上是把上一个子 expression 倒栈) // 遇到右括号 / 结尾开始倒栈 // 对于倒栈,只剩下 +- 需要处理。 std::stack undealt_tokens, ready_tokens; std::optional temp_token; for (const auto& token : expression) { if (token == '*' || token == '/') { temp_token = token; continue; } if (temp_token.has_value()) { int a = undealt_tokens.top().get_number(); undealt_tokens.pop(); undealt_tokens.emplace( temp_token == '*' ? a * token.get_number() : a / token.get_number() ); temp_token.reset(); continue; } if (token == ')') { calculate_chunk(undealt_tokens, ready_tokens); continue; } undealt_tokens.push(token); } calculate_chunk(undealt_tokens, ready_tokens); assert(undealt_tokens.size() == 1); return undealt_tokens.top().get_number(); } int n; std::string s; int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cin >> n; for (int _ = 0; _ < n; _++) { std::cin >> s; std::cout << calculate(parse_string(s)) << std::endl; } return 0; }