From 654105c8efd63d89930e95bd391f64d4072acfdf Mon Sep 17 00:00:00 2001 From: Kumar Yash Date: Sun, 17 Oct 2021 05:57:11 +0530 Subject: [PATCH] feat: add infix to postfix converter algorithm (#869) * add infix to postfix converter algorithm * docs: documentation changes * docs: documentation changes * updating DIRECTORY.md * docs: documentation changes * fix: continuous integration * [test, docs]: add test case, documentation changes * docs: documentation changes * fix: continuous integration * docs: documentation changes * docs: documentation changes * test: add new test Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: David Leal --- DIRECTORY.md | 1 + conversions/infix_to_postfix2.c | 164 ++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 conversions/infix_to_postfix2.c diff --git a/DIRECTORY.md b/DIRECTORY.md index 5f59f2b5..2b405e29 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -27,6 +27,7 @@ * [Hexadecimal To Octal](https://github.com/TheAlgorithms/C/blob/master/conversions/hexadecimal_to_octal.c) * [Hexadecimal To Octal2](https://github.com/TheAlgorithms/C/blob/master/conversions/hexadecimal_to_octal2.c) * [Infix To Postfix](https://github.com/TheAlgorithms/C/blob/master/conversions/infix_to_postfix.c) + * [Infix To Postfix2](https://github.com/TheAlgorithms/C/blob/master/conversions/infix_to_postfix2.c) * [Int To String](https://github.com/TheAlgorithms/C/blob/master/conversions/int_to_string.c) * [Octal To Binary](https://github.com/TheAlgorithms/C/blob/master/conversions/octal_to_binary.c) * [Octal To Decimal](https://github.com/TheAlgorithms/C/blob/master/conversions/octal_to_decimal.c) diff --git a/conversions/infix_to_postfix2.c b/conversions/infix_to_postfix2.c new file mode 100644 index 00000000..e0f58400 --- /dev/null +++ b/conversions/infix_to_postfix2.c @@ -0,0 +1,164 @@ +/** + * @file + * @brief [Infix to Postfix converter](https://www.includehelp.com/c/infix-to-postfix-conversion-using-stack-with-c-program.aspx) implementation + * @details + * The input infix expression is of type string upto 24 characters. + * Supported operations- '+', '-', '/', '*', '%' + * @author [Kumar Yash](https://github.com/kumaryash18) + * @see infix_to_postfix.c + */ + +#include /// for IO operations +#include /// for strlen(), strcmp() +#include /// for isalnum() +#include /// for exit() +#include /// for uint16_t, int16_t +#include /// for assert + +/** + * @brief array implementation of stack using structure + */ +struct Stack { + char stack[10]; ///< array stack + int top; ///< stores index of the top element +}; +struct Stack st; ///< global declaration of stack st + +/** + * @brief Function to push on the stack + * @param opd character to be pushed in the stack + * @returns void + */ +void push(char opd) { + if(st.top == 9) { // overflow condition + printf("Stack overflow..."); + exit(1); + } + st.top++; + st.stack[st.top] = opd; +} + +/** + * @brief Function to pop from the stack + * @returns popped character + */ +char pop() { + char item; ///< to store the popped value to be returned + if(st.top == -1) { // underflow condition + printf("Stack underflow..."); + exit(1); + } + item = st.stack[st.top]; + st.top--; + return item; +} + +/** + * @brief Function to check whether the stack is empty or not + * @returns 1 if the stack IS empty + * @returns 0 if the stack is NOT empty + */ +uint16_t isEmpty() { + if(st.top == -1) { + return 1; + } + return 0; +} + +/** + * @brief Function to get top of the stack + * @returns top of stack + */ +char Top() { + return st.stack[st.top]; +} + +/** + * @brief Function to check priority of operators + * @param opr operator whose priority is to be checked + * @returns 0 if operator is '+' or '-' + * @returns 1 if operator is '/' or '*' or '%' + * @returns -1 otherwise + */ +int16_t priority(char opr) { + if(opr == '+' || opr == '-') { + return 0; + } + else if(opr == '/' || opr == '*' || opr == '%') { + return 1; + } + else { + return -1; + } +} + +/** + * @brief Function to convert infix expression to postfix expression + * @param inf the input infix expression + * @returns output postfix expression + */ +char *convert(char inf[]) { + static char post[25]; ///< to store the postfix expression + int i; ///< loop iterator + int j = 0; ///< keeps track of end of postfix string + for(i = 0; i < strlen(inf); i++) { + if(isalnum(inf[i])) { // if scanned element is an alphabet or number + post[j] = inf[i]; // append in postfix expression + j++; + } + else if(inf[i] == '(') { // if scanned element is opening parentheses + push(inf[i]); // push on stack. + } + else if(inf[i] == ')') { // if scanned element is closing parentheses, + while(Top() != '(') { // pop elements from stack and append in postfix expression + post[j] = pop(); // until opening parentheses becomes top. + j++; + } + pop(); // pop opening parentheses + } + else { // if scanned element is an operator + while( (!isEmpty()) && (priority(inf[i]) <= priority(Top())) ) { // pop and append until stack becomes + post[j] = pop(); // empty or priority of top operator + j++; // becomes smaller than scanned operator + } // '(' has priority -1 + push(inf[i]); // push the scanned operator + } + } + while(!isEmpty()) { // pop and append residual operators from stack + post[j] = pop(); + j++; + } + post[j] = '\0'; // end postfix string with null character + return post; +} + +/** + * @brief Self-test implementations + * @returns void + */ +static void test() { + /* check sample test case + input- "(A/(B-C)*D+E)" + expected output- "ABC-/D*E+" + */ + assert(strcmp(convert("(A/(B-C)*D+E)"), "ABC-/D*E+") == 0); /// this ensures that the algorithm works as expected + /* input- "7-(2*3+5)*(8-4/2)" + expected output- "723*5+842/-*-" + */ + assert(strcmp(convert("7-(2*3+5)*(8-4/2)"), "723*5+842/-*-") == 0); /// this ensures that the algorithm works as expected + printf("All tests have successfully passed!\n"); +} + +/** + * @brief Main function + * @returns 0 on exit + */ +int main() { + st.top = -1; /// initialize + test(); /// run self-test implementations + char inf[25]; ///< to store input infix expression + printf("Enter infix: "); + scanf("%s", inf); + printf("Postfix: %s", convert(inf)); + return 0; +}