The Algorithms logo
The Algorithms
Acerca deDonar

Infix to Postfix 2

/**
 * @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;
}