mirror of https://github.com/TheAlgorithms/C
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 <halfpacho@gmail.com>
This commit is contained in:
parent
9bbec45d13
commit
654105c8ef
|
@ -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)
|
||||
|
|
|
@ -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 <stdio.h> /// for IO operations
|
||||
#include <string.h> /// for strlen(), strcmp()
|
||||
#include <ctype.h> /// for isalnum()
|
||||
#include <stdlib.h> /// for exit()
|
||||
#include <stdint.h> /// for uint16_t, int16_t
|
||||
#include <assert.h> /// 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;
|
||||
}
|
Loading…
Reference in New Issue