#include #include #include namespace { template void pop_and_push(std::vector &src, std::vector &dst) { assert(src.size()); dst.push_back(src.back()); src.pop_back(); } int priority(char op) { switch (op) { case '(': case ')': return 0; case '+': case '-': return 1; case '*': case '/': return 2; case '^': return 3; default: assert(false); } } enum assoc_t { LEFT, RIGHT, NONE }; assoc_t associativity(char op) { assert(!std::isdigit(op)); switch (op) { case '(': case ')': return assoc_t::NONE; case '^': return assoc_t::RIGHT; default: return assoc_t::LEFT; } } bool pop_operator(std::vector &op_stack, char o1) { if (op_stack.empty()) { return false; } char o2 = op_stack.back(); if (o2 == '(') { return false; } int o1_priority = priority(o1); int o2_priority = priority(o2); return o2_priority > o1_priority || (o2_priority == o1_priority && associativity(o1) == assoc_t::LEFT); } } // namespace std::string to_postfix(std::string infix) { std::vector output_queue; std::vector operator_stack; for (char token : infix) { if (std::isdigit(token)) { output_queue.push_back(token); } else if (token == '(') { operator_stack.push_back(token); } else if (token == ')') { while (operator_stack.back() != '(') { assert(operator_stack.size()); pop_and_push(operator_stack, output_queue); } assert(operator_stack.back() == '('); operator_stack.pop_back(); } else { while (pop_operator(operator_stack, token)) { pop_and_push(operator_stack, output_queue); } operator_stack.push_back(token); } } while (operator_stack.size()) { assert(operator_stack.back() != '('); pop_and_push(operator_stack, output_queue); } return std::string(output_queue.begin(), output_queue.end()); } int main() { assert(to_postfix("2+7*5") == "275*+"); assert(to_postfix("3*3/(7+1)") == "33*71+/"); assert(to_postfix("5+(6-2)*9+3^(7-1)") == "562-9*+371-^+"); assert(to_postfix("(5-4-1)+9/5/2-7/1/7") == "54-1-95/2/+71/7/-"); assert(to_postfix("1^2^3") == "123^^"); return 0; }