CSCE 3110 Data Structures & Algorithm Analysis
Rada Mihalcea http://www.cs.unt.edu/~rada/CSCE3110 Stack Applications Reading: Chap. 3 Weiss
Applications
Infix to Postfix conversion [Evaluation of Expressions]
Evaluation of Expressions
X=a/b-c+d*e-a*c
a = 4, b = c = 2, d = e = 3
Interpretation 1: ((4/2)-2)+(3*3)-(4*2)=0 + 8+9=1
Interpretation 2: (4/(2-2+3))*(3-4)*2=(4/3)*(-1)*2=-2.66666 How to generate the machine instructions corresponding to a given expression? precedence rule + associative rule
Token Operator () [] -> . -- ++ -- ++ ! -+ &* sizeof (type) */%
Precedence1 Associativity left-to-right
function call 17 array element struct or union member increment, decrement2 16 decrement, increment3 logical not ones complement unary minus or plus address or indirection size (in bytes) type cast mutiplicative 15
left-to-right right-to-left
14 13
right-to-left Left-to-right
+-
binary add or subtract
12 11 10 9 8 7 6 5 4
left-to-right left-to-right left-to-right left-to-right left-to-right left-to-right left-to-right left-to-right left-to-right
<< >> shift > >= < <= == != & ^ relational equality bitwise and bitwise exclusive or bitwise or && logical and logical or
?:
conditional
3 2
right-to-left right-to-left
= += -= assignment /= *= %= <<= >>= &= ^= = , comma
left-to-right
user
compiler
Infix 2+3*4 a*b+5 (1+2)*7 a*b/c (a/(b-c+d))*(e-a)*c a/b-c+d*e-a*c
Postfix 234*+ ab*5+ 12+7* ab*c/ abc-d+/ea-*c* ab/c-de*ac*-
Postfix: no parentheses, no precedence
Token 6 2 / 3 4 2 * +
[0] 6 6 6/2 6/2 6/2-3 6/2-3 6/2-3 6/2-3 6/2-3+4*2
Stack [1] 2 3 4 4 4*2
Top [2] 0 1 0 1 0 1 2 2 1 0
Infix to Postfix
Assumptions: operators: +, -, *, /, % operands: single digit integer
#define MAX_STACK_SIZE 100 /* maximum stack size */ #define MAX_EXPR_SIZE 100 /* max size of expression */ typedef enum{1paran, rparen, plus, minus, times, divide, mod, eos, operand} precedence; int stack[MAX_STACK_SIZE]; /* global stack */ char expr[MAX_EXPR_SIZE]; /* input string */
Evaluation of Postfix Expressions
int eval(void) { /* evaluate a postfix expression, expr, maintained as a global variable, \0 is the the end of the expression. The stack and top of the stack are global variables. get_token is used to return the token type and the character symbol. Operands are assumed to be single character digits */ precedence token; char symbol; int op1, op2; int n = 0; /* counter for the expression string */ int top = -1; token = get_token(&symbol, &n); while (token != eos) { if (token == operand) push(&top, symbol-0); /* stack insert */
else { /* remove two operands, perform operation, and return result to the stack */ op2 = pop(&top); /* stack delete */ op1 = pop(&top); switch(token) { case plus: push(&top, op1+op2); break; case minus: push(&top, op1-op2); break; case times: push(&top, op1*op2); break; case divide: push(&top, op1/op2); break; case mod: push(&top, op1%op2); } } token = get_token (&symbol, &n); } return pop(&top); /* return result */ }
precedence get_token(char *symbol, int *n) { /* get the next token, symbol is the character representation, which is returned, the token is represented by its enumerated value, which is returned in the function name */ *symbol =expr[(*n)++]; switch (*symbol) { case ( : return lparen; case ) : return rparen; case +: return plus; case - : return minus;
case / : return divide; case * : return times; case % : return mod; case \0 : return eos; default : return operand; /* no error checking, default is operand */ } }
Infix to Postfix Conversion
(Intuitive Algorithm)
(1) Fully parenthesized expression a / b - c + d * e - a * c --> ((((a / b) - c) + (d * e)) (a * c)) All operators replace their corresponding right parentheses. ((((a / b) - c) + (d * e)) (a * c))
(2)
(3)
/ Delete all parentheses. ab/c-de*+ac*two passes
+*
-*
The orders of operands in infix and postfix are the same. a + b * c, * > +
Token a + b * c eos
Stack [0] [1] [2] + + + +
Top -1 0 0 1 1 -1
Output a a ab ab abc abc*=
* *
a *1 (b +c) *2 d
Token a *1 ( b + c ) *2 d eos
Stack [0] [1] [2] *1 *1 *1 *1 *1 *1 *2 *2 *2
Top -1 0 1 1 2 2 0 0 0 0
Output a a a ab ab abc abc+ abc+*1 abc+*1d abc+*1d*2
( ( ( (
+ + match )
*1 = *2
Rules
(1) Operators are taken out of the stack as long as their in-stack precedence is higher than or equal to the incoming precedence of the new operator. ( has low in-stack precedence, and high incoming precedence. ( 0 20 ) 19 19 + 12 12 12 12 * 13 13 / 13 13 % 13 13 eos 0 0
(2)
isp icp
precedence stack[MAX_STACK_SIZE]; /* isp and icp arrays -- index is value of precedence lparen, rparen, plus, minus, times, divide, mod, eos */ static int isp [ ] = {0, 19, 12, 12, 13, 13, 13, 0}; static int icp [ ] = {20, 19, 12, 12, 13, 13, 13, 0};
isp: in-stack precedence icp: incoming precedence
Infix to Postfix
void postfix(void) { /* output the postfix of the expression. The expression string, the stack, and top are global */ char symbol; precedence token; int n = 0; int top = 0; /* place eos on stack */ stack[0] = eos; for (token = get _token(&symbol, &n); token != eos; token = get_token(&symbol, &n)) { if (token == operand) printf (%c, symbol); else if (token == rparen ){
Infix to Postfix (contd)
/*unstack tokens until left parenthesis */ while (stack[top] != lparen) print_token(delete(&top)); pop(&top); /*discard the left parenthesis */ } else{ /* remove and print symbols whose isp is greater than or equal to the current tokens icp */ while(isp[stack[top]] >= icp[token] ) print_token(delete(&top)); push(&top, token); } } while ((token = pop(&top)) != eos) print_token(token); print(\n);