From 54483a16512865492a870af0d5dc792dedfb14d8 Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Wed, 3 Aug 2022 09:46:55 +0200 Subject: [PATCH] 4kyu: add infix to postfix converter Signed-off-by: Matej Focko --- 4kyu/infix_to_postfix_converter/solution.cpp | 108 +++++++++++++++++++ README.md | 1 + 2 files changed, 109 insertions(+) create mode 100644 4kyu/infix_to_postfix_converter/solution.cpp diff --git a/4kyu/infix_to_postfix_converter/solution.cpp b/4kyu/infix_to_postfix_converter/solution.cpp new file mode 100644 index 0000000..71fbf35 --- /dev/null +++ b/4kyu/infix_to_postfix_converter/solution.cpp @@ -0,0 +1,108 @@ +#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; +} diff --git a/README.md b/README.md index 406f9dc..3fb4983 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ - [Permutations](https://www.codewars.com/kata/5254ca2719453dcc0b00027d) - [solution](4kyu/permutations) - [Matrix Determinant](https://www.codewars.com/kata/52a382ee44408cea2500074c) - [solution](4kyu/matrix_determinant) +- [Infix to Postfix Converter](https://www.codewars.com/kata/52e864d1ffb6ac25db00017f) - [solution](4kyu/infix_to_postfix_converter) ### JS