Program
#include #include #include #define N 80 typedef enum {FALSE, TRUE} bool; #include "stack.h" #include "queue.h" #define NOPS 7 char operators [] = "()^/*+-"; int priorities[] = {4,4,3,2,2,1,1}; char associates[] = " RLLLL"; char t[N]; char *tptr = t; // this is where prefix will be saved. int getIndex( char op ) { /* * returns index of op in operators. */ int i; for( i=0; i−1; } int getPriority( char op ) { /* * returns priority of op. */ return priorities[ getIndex(op) ]; } char getAssociativity( char op ) { /* * returns associativity of op. */ return associates[ getIndex(op) ]; } void processOp( char op, queue *q, stack *s ) { /* * performs processing of op. */ switch(op) { case ')': printf( " S pushing )... " ); sPush( s, op ); break; case '(': while( !qEmpty(q) ) { *tptr++ = qPop(q); printf( " Q popping %c... ", *(tptr-1) ); } while( !sEmpty(s) ) { char popop = sPop(s); printf( " S popping %c... ", popop ); if( popop == ')' ) break; *tptr++ = popop; } break; default: { int priop; // priority of op. char topop; // operator on stack top. int pritop; // priority of topop. char asstop; // associativity of topop. while( !sEmpty(s) ) { priop = getPriority(op); topop = sTop(s); pritop = getPriority(topop); asstop = getAssociativity(topop); if( pritop < priop || (pritop == priop && asstop == 'L') || topop == ')' ) // IMP. break; while( !qEmpty(q) ) { *tptr++ = qPop(q); printf( " Q popping %c... ", *(tptr-1) ); } *tptr++ = sPop(s); printf( " S popping %c... ", *(tptr-1) ); } printf( " S pushing %c... ", op ); sPush( s, op ); break; } } } bool isop( char op ) { /* * is op an operator? */ return (getIndex(op) != −1); } char *in2pre( char *str ) { /* * returns valid infix expr in str to prefix. */ char *sptr; queue q = {NULL}; stack s = NULL; char *res = (char *)malloc( N*sizeof(char) ); char *resptr = res; tptr = t; for( sptr=str+strlen(str)−1; sptr!=str−1; -sptr ) { printf( "processing %c tptr-t=%d... ", *sptr, tptr-t ); if( isalpha(*sptr) ) // if operand. qPush( &q, *sptr ); else if( isop(*sptr) ) // if valid operator. processOp( *sptr, &q, &s ); else if( isspace(*sptr) ) // if whitespace. ; else { fprintf( stderr, "ERROR:invalid char %c. ", *sptr ); return ""; } } while( !qEmpty(&q) ) { *tptr++ = qPop(&q); printf( " Q popping %c... ", *(tptr-1) ); } while( !sEmpty(&s) ) { *tptr++ = sPop(&s); printf( " S popping %c... ", *(tptr-1) ); } *tptr = 0; printf( "t=%s. ", t ); for( -tptr; tptr!=t−1; -tptr ) { *resptr++ = *tptr; } *resptr = 0; return res; } int main() { char s[N]; puts( "enter infix freespaces max 80." ); gets(s); while(*s) { puts( in2pre(s) ); gets(s); } return 0; }
Explanation
step |
remaining expression |
scanned element |
queue of operands |
stack of operators |
prefix output |
---|---|---|---|---|---|
0 |
a*b+c/d |
nil |
empty |
empty |
nil |
1 |
a*b+c/ |
d |
d |
empty |
nil |
2 |
a*b+c |
/ |
d |
/ |
nil |
3 |
a*b+ |
c |
d c |
/ |
nil |
4 |
a*b |
+ |
empty |
+ |
dc/ |
5 |
a* |
b |
b |
+ |
dc/ |
6 |
a |
* |
b |
* + |
dc/ |
7 |
nil |
a |
b a |
* + |
dc/ |
8 |
nil |
nil |
empty |
empty |
dc/ba*+ |
The final prefix output we get is dc/ba*+, whose reverse is +*ab/cd, which is indeed the prefix equivalent of the input infix expression a*b+c*d. Note that all the operands are simply pushed to the queue in steps 1, 3, 5, and 7. In step 2, the operator / is pushed to the empty stack of operators.
In step 4, the operator + is checked against the elements in the stack. Since / (division) has higher priority than + (addition), the queue is emptied to the prefix output (thus we get ‘dc’ as the output) and then the operator / is written (thus we get ‘dc/’ as the output). The operator + is then pushed to the stack. In step 6, the operator * is checked against the stack elements. Since * has a higher priority than +, * is pushed to the stack. Step 8 signifies that all of the infix expression has been scanned. Thus, the queue of operands is emptied to the prefix output (to get ‘dc/ba’), followed by emptying of the stack of operators (to get ‘dc/ba*+’).
Points to Remember
Two stacks are represented in an array twostacks[0…N–1], such that one stack starts from start of the array and grows towards its end while the other one starts from the end of the array and grows towards the start. Thus at any time, the maximum number of elements that the two stacks together can accommodate is N. Write functions Push(stacki, data) and Delete(stacki) to add element data and to delete an element from stack number stacki, 1 <= stacki <= 2. The functions should be able to add elements to the stacks as long as there are fewer than N elements in both stacks together.
Program
#include #define N 10 // combined size of the two stacks. #define EINDEXOUTOFBOUND −1 // error code on overflow in the stacks. #define SUCCESS 0 // success code. typedef int type; // type of each data item. type twostacks[N]; // stacks implemented using array. int stop1 = −1; // pointer for stack 1. int stop2 = N; // pointer for stack 2. int sPush( int stacki, type data ) { /* * pushes data on top of stacki. * returns error on overflow. */ if( stop2-stop1 == 1 ) // overflow. return EINDEXOUTOFBOUND; if( stacki == 1 ) { // first stack. twostacks[ ++stop1 ] = data; } else { // second stack. twostacks[ -stop2 ] = data; } return SUCCESS; } int sDelete( int stacki ) { /* * deletes element at top from stacki. */ printf( "deleting from stack %d... ", stacki ); if( stacki == 1 ) { // first stack. if( stop1 >= 0 ) -stop1; else return EINDEXOUTOFBOUND; } else { // second stack. if( stop2 < N ) ++stop2; else return EINDEXOUTOFBOUND; } return SUCCESS; } void sPrint() { /* * prints the two stacks. */ int i; for( i=0; i<=stop1; ++i ) printf( "%d ", twostacks[i] ); printf( ": " ); for( i=stop2; i
Explanation
Points to Remember
if( stacktop == NULL ) error("stack empty.");.
Part I - C Language
Part II - Data Structures
Part III - Advanced Problems in Data Structures