Stacks This presentation shows – how to implement the stack – how it can be used in real applications
Stack Definitions Stack: a linear data structure where access is restricted to the most recently inserted item. Stack operations: -Push: add an item to the stack. -Pop: remove an item from the stack. The element to be removed is the last item added. -Isempty: Check if the stack is empty Derived operations: -Top: read the element on the top (can be implemented using one pop followed by read and push the element again) -DeleteStack: Pop all elements of the stack (can be elemented by successive calls to pop)
Stack Interface A typical stack interface (function declaration): void push(Thing newThing); Thing pop(); Thing top(); char isempty(); Thing: could be char, int, float, double, or structure isempty() returns 1 if stack is empty, zero otherwise
6 th Mar 2007 Stack Implementation: Array A stack can be implemented as an array A and an integer top that records the index of the top of the stack. For an empty stack, set top to -1. When push(X) is called, increment top, and write X to A[top]. When pop() is called, decrement top. When top() is called, return A[top].
Example A top A B Push A Push B top 0 1 A B 0 Pop
Stack Implementation: Linked List A stack can be implemented as a linked list A with a pointer head that points to the top of the stack. For an empty stack, set head to NULL. When push(X) is called, add node to the front (see previous lecture) When pop() is called, remove node from the front (see previous lecture)
Stack Implementation: Array #include # define maxstacksize 1000; Typedef struct elem{ // Stack item represented as a strcture int dataitem1; char dataitem2; }elem; elem stackarray[maxstacksize]; int top=-1; void push(elem newelem); elem pop(); elem top(); char isempty(); // returns 1 if true, zero otherwise Void push(elem newelem){ if(top==maxstacksize-1){ printf (“stack is full \n”); return(); } top++; stackarray[top]=newelem; } Type Definitions & ConstantsCreating empty stackStack Function declarationFunction implementation
Stack Implementation: Array elem pop(){ if(top==-1){ printf (“stack is empty \n”); } else{ top--; return (stackarray[top+1]); } elem top(){ if(top==-1){ printf (“stack is empty \n”); return(); } return (stackarray[top]); } char isempty(){ if (top==-1){return (1);} else{return (0);} } Function implementation
Stack Implementation: Linked List #include Typedef struct elem{ // Stack item represented as a strcture int dataitem1; char dataitem2; struct elem* next; }elem; elem* headptr; void push(elem newelem); elem pop(); elem top(); char isempty(); // returns 1 if true, zero otherwise Void push(elem newelem){ elem* new = (node*) malloc( sizeof( struct t_node ) ); if(new==NULL) {printf(“not enough memory\n”); return (0);} *new = *newelem; new->next=NULL; new->next = *headptr; *headptr = new; return(1); } Type Definitions & ConstantsCreating empty stackStack Function declarationFunction implementation
Stack Implementation: Linked List elem pop(){ elem tmp; elem* tmp_ptr=headptr; if(isempty()){ printf (“stack is empty \n”); return(); } tmp=*headptr; headptr = headptr->next; free(tmp_ptr); return (tmp); } elem top(){ if(isempty()){ printf (“stack is empty \n”); return(); } return (*headptr); } char isempty(){ if (headptr==NULL){return (1);} else{return (0);} } Function implementation
Stack in Action: Infix Calculator Problem: Build an infix calculator –Input: A mathematical expression of integer numbers represented by a string. –Ouput: A numerical value evaluating the expresion -Constraint: each closed bracket should be in the form “(term operation term)”, where term could be a number or another bracket, and operation is either (‘+’, ‘-’, ‘*’, ‘/’). -Example: ((3*4)-5)+2) accepted input -Example: ((3*4)-5+2) not accepted input Here, we will assume that the user carefully enters the data. But it is recommended you think of a function that checks if the user input is correct or not Think what the word “infix” mean; what is related could exist? Here, we will assume that the user carefully enters the data. But it is recommended you think of a function that checks if the user input is correct or not Think what the word “infix” mean; what is related could exist?
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows ( ((3*4)-5)+2) Push element
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows ( ( ((3*4)-5)+2) Push element
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows 3 ( ( ((3*4)-5)+2) Push element
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows * 3 ( ( ((3*4)-5)+2) Push element
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows 4 * 3 ( ( ((3*4)-5)+2) Push element
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows 4 * 3 ( ( ((3*4)-5)+2) Do not push element, pop ‘4’, ‘*’, ‘3’, ‘)’ and evaluate them, then return total back
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows 12 ( ((3*4)-5)+2) Do not push element, pop ‘4’, ‘*’, ‘3’, ‘)’ and evaluate them, then return total back
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows - 12 ( ((3*4)-5)+2) Push element
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows ( ((3*4)-5)+2) Push element
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows ( ((3*4)-5)+2) Do not push element, pop ‘5’, ‘-’, ‘12’, ‘)’ and evaluate them, then return total back
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows 7 ( ((3*4)-5)+2) Do not push element, pop ‘5’, ‘-’, ‘12’, ‘)’ and evaluate them, then return total back
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows ( ((3*4)-5)+2) Push elements ‘+’ & ‘2’
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows ( ((3*4)-5)+2) Do not push element, pop ‘2’, ‘+’, ‘7’, ‘)’ and evaluate them, then return total back
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows 9 ((3*4)-5)+2) Do not push element, pop ‘2’, ‘+’, ‘7’, ‘)’ and evaluate them, then return total back
Stack in Action: Infix Calculator The idea of the algorithm is Push elements as long as elements are not “)” Once you meet “)”, start pop elements until you find “(”and evaluate sub expression store it in variable total, pop also the first “(” you see. Push the value total back to the stack Example: ((3*4)-5)+2) is evaluated as follows ((3*4)-5)+2) Return 9
Main Interface for Calc. Program //// stack declaration and implementation is given above int parse_expres(char* inputstr, elem* expres_tokens); float evaluate_expres(elem* expres_tokens, int expres_length); int main(int argc, char *argv[]) { char inchar; char inputstr[1000]; float retval; elem expres_tokens[1000]; int expres_length=0; while(1){ printf(“Enter 0 to exit, or 1 to enter an expression\n”); scanf(“%c”,&inchar); if(char==‘0’){ exit(0);} else if(char==‘1’){ printf(“Enter an expression\n”); scanf(“%s”,inputstr); expres_length=parse_expres(inputstr, expres_tokens); retval=evaluate_expres(expres_tokens, expres_length); print(“Expression evaluates to %f \n”, retval); } //else } // while return(0); } // main Function call Function declaration
Parsing the Expression int parse_expres(char* inputstr, elem* expres_tokens){ char numdigits[100]; numdigits[j]=0; // end of string int i=0; int j=0; int k=0; int val; int strlength=0; strlength=strlen(inputstr); for (i=0;i<strlength;i++){ if(isdigit(inputstr[i])){ numdigits[j]=inputstr[i]; j++; numdigits[j]=0; // end of string } else{ j=0; if(strlen(numdigit)>0){ // indicates I just read a number val=atoi(numdigits); numdigits[0]=0; // make the string empty express_token[k].dataitem1=0; express_token[k].dataitem2=val; } if(inputstr[i]==‘+’) expres_token[k].dataitem1=1; if(inputstr[i]==‘-’) expres_token[k].dataitem1=2; if(inputstr[i]==‘*’) expres_token[k].dataitem1=3; if(inputstr[i]==‘/’) expres_token[k].dataitem1=4; if(inputstr[i]==‘(’) expres_token[k].dataitem1=5; if(inputstr[i]==‘)’) expres_token[k].dataitem1=6; k++; } //else }// for loop } // function
Parsing the Expression int parse_expres(char* inputstr, elem* expres_tokens){ char numdigits[100]; numdigits[j]=0; // end of string int i=0; int j=0; int k=0; int val; int strlength=0; strlength=strlen(inputstr); for (i=0;i<strlength;i++){ if(isdigit(inputstr[i])){ numdigits[j]=inputstr[i]; j++; numdigits[j]=0; // end of string } else{ j=0; if(strlen(numdigit)>0){ // indicates I just read a number val=atoi(numdigits); numdigits[0]=0; // make the string empty express_token[k].dataitem1=0; express_token[k].dataitem2=val; } if(inputstr[i]==‘+’) expres_token[k].dataitem1=1; if(inputstr[i]==‘-’) expres_token[k].dataitem1=2; if(inputstr[i]==‘*’) expres_token[k].dataitem1=3; if(inputstr[i]==‘/’) expres_token[k].dataitem1=4; if(inputstr[i]==‘(’) expres_token[k].dataitem1=5; if(inputstr[i]==‘)’) expres_token[k].dataitem1=6; k++; } //else }// for loop } // function The function isdigit checks if the input character is in the set {0,1,2,3,…,9}
Evaluate the Expression float evaluate_expres(elem* expres_tokens, int expres_length){ int i=0; elem tmpelem; int value1, int value2, int optype, float total; for(i=0;i<expres_length;i=++){ if(expres_tokens[i].dataitem1!=6){ push(expres_tokens[i]); } else{ if(isempty()==0){tmpelem=pop();} else{printf(“Wrong expres”); exit(1);} value1=tmpelem.dataitem2; // pops value if(isempty()==0){tmpelem=pop();} else{printf(“Wrong expres”); exit(1);} optype=tmpelem.dataitem1; //pops operation if(isempty()==0){tmpelem=pop();} else{printf(“Wrong expres”); exit(1);} value2=tmpelem.dataitem2; // the following pops out “(” if(isempty()==0){tmpelem=pop();} else{printf(“Wrong expres”); exit(1);} if(optype==1){total=value1+value2;} if(optype==2){total=value2-value1;} if(optype==3){total=value1*value2;} if(optype==4){total=(float)value2/(float)value1;} tmpelem.dataitem1=0; tmpelem.dataitem2=total; push(tmpelem); } else } // endfor if(isempty()==0){tmpelem=pop();} else{printf(“Wrong expres”); exit(1);} if(isempty()){return(tmpelem.dataitem2);}else{printf(“Wrong expres”); exit(1);} } // function
Evaluate the Expression float evaluate_expres(elem* expres_tokens, int expres_length){ int i=0; elem tmpelem; int value1, int value2, int optype, float total; for(i=0;i<expres_length;i=++){ if(expres_tokens[i].dataitem1!=6){ push(expres_tokens[i]); } else{ if(isempty()==0){tmpelem=pop();} else{printf(“Wrong expres”); exit(1);} value1=tmpelem.dataitem2; // pops value if(isempty()==0){tmpelem=pop();} else{printf(“Wrong expres”); exit(1);} optype=tmpelem.dataitem1; //pops operation if(isempty()==0){tmpelem=pop();} else{printf(“Wrong expres”); exit(1);} value2=tmpelem.dataitem2; // the following pops out “(” if(isempty()==0){tmpelem=pop();} else{printf(“Wrong expres”); exit(1);} if(optype==1){total=value1+value2;} if(optype==2){total=value2-value1;} if(optype==3){total=value1*value2;} if(optype==4){total=(float)value2/(float)value1;} tmpelem.dataitem1=0; tmpelem.dataitem2=total; push(tmpelem); } else } // endfor if(isempty()==0){tmpelem=pop();} else{printf(“Wrong expres”); exit(1);} if(isempty()){return(tmpelem.dataitem2);}else{printf(“Wrong expres”); exit(1);} } // function If stack is empty before finishing evaluation, then expression must be syntactically wrong If stack remains non-empty after finishing expression, then expression must be syntactically wrong Without the constraint on the expression, we could have more than pops. If stack is empty before finishing evaluation, then expression must be syntactically wrong If stack remains non-empty after finishing expression, then expression must be syntactically wrong Without the constraint on the expression, we could have more than pops.
T HE E ND