DCO20105 Data structures and algorithms Lecture 12: Stack and Expression Evaluation Stack • basic operations of a stack • its implementation using a vector • applications of stack Expression Evaluation • Infix, Prefix, and Postfix expressions • Implementation of evaluating a postfix expression -- By Rossella Lau Rossella Lau Lecture 12, DCO20105, Semester A,2005-6 Stack Stack is an ordered list of items, ordered in the input sequence Basically, items are inserted and deleted at one end, called the top of the stack are last in first out (LIFO) An example: The original Add an item Take an item C C B A Rossella Lau Add an item B A D B A E D B A Lecture 12, DCO20105, Semester A,2005-6 Operations of a stack Basic: push() – to add an item pop() – to remove an item Assistance: size() – returns the number of items in a stack empty() – to check if a stack is empty top() – returns the first element of a stack; note that in a queue, it is called front() Rossella Lau Lecture 12, DCO20105, Semester A,2005-6 Exercises Ford: Rossella Lau 7: 13,14; 8:11 Lecture 12, DCO20105, Semester A,2005-6 Implementation of a stack using a vector // Stack.h template<class T> class Stack { private: vector<T> stack; public: void push(T const & item) {stack.push_back(item);} T & pop() {T t(top()); stack.pop_back(); return t;} size_t size() const { return stack.size();} bool empty() const { return stack.empty();} T const & top() const { return stack.back();} }; Rossella Lau Lecture 12, DCO20105, Semester A,2005-6 Applications of stack Nested parentheses check Expression evaluation The underlying structure for recursion Function calls (and its associated variables), e.g., : init init push pop check check check check main main main main Rossella Lau push … Lecture 12, DCO20105, Semester A,2005-6 A stack application: nested parentheses check Consider the parentheses in mathematical expressions 1. Equal number of right and left parentheses 2. Every right parenthesis is preceded by a matching parenthesis Wrong expressions: ((A+B) violate condition 1 )A+B(-C violate condition 2 Solution: nesting depth parenthesis count Rossella Lau Lecture 12, DCO20105, Semester A,2005-6 Use of nesting depth and parenthesis count Nesting depth: left parenthesis: open a scope right parenthesis: close a scope nesting depth at a particular point is the number of scopes that have been opened but not closed Parenthesis count: at a particular point as the number of left parentheses minus the number of right parentheses if the count is not negative, it is the nesting depth Check parentheses use by checking if parenthesis count: is greater than or equal to 0 at any point is equal to 0 at the end of the expression of course, checking should include the parenthesis type: {}, [],() Rossella Lau Lecture 12, DCO20105, Semester A,2005-6 Use of a stack to check For each left parenthesis, do a push For each right parenthesis, do a pop and make sure the item popped is equal to the right parenthesis (same type) If the stack is empty when doing a pop ERROR If the stack is not empty when the expression ends ERROR Examples of checking invalid expressions: ((A+B) [(A+B]) )A+B(-C ( ( ( Rossella Lau ( ( !empty(s) Cannot pop ( [ ( [ Type mismatch Lecture 12, DCO20105, Semester A,2005-6 Algorithm to check pairs of parentheses bool check(string expression){ valid = true stack<char> brackets while (expression not end){ read a symbol (symb) if symb is a left bracket brackets.push(symb) if symb is a right bracket{ if brackets.empty() valid=false if brackets.front() not match symb valid = false brackets.pop() } } if !brackets.empty() valid = false return valid} Rossella Lau {x+(y-[a+b])*c-(d+e)}/(h-(j-(k-[l-n]))) [ [ ( { ( { {x+(y-[ {…a+b]) ( ( { { {…*c-( {…d+e) [ { {…} [ ( ( ( …/(h-(j-(k-[ ( ( ( …l-n]))) Lecture 12, DCO20105, Semester A,2005-6 Expression evaluation An expression is a series of operators and operands Operators: +, -, *, /, %, $ (exponentiation) Operands: the values going to be operated Three representations of an expression: Infix: The usual form, operator is between operands Prefix: the operator is in front of the operand(s) Postfix: the operand(s) is(are) in front of the operator Rossella Lau Lecture 12, DCO20105, Semester A,2005-6 Examples of Prefix Expressions Infix Prefix A+B +AB A+B-C (A+B)*(C-D) A$B*C-D+E/F/(G+H) ((A+B)*C-(D-E))$(F+G) A-B/(C*D$E) Rossella Lau -+ABC *+AB-CD +-*$ABCD//EF+GH $-*+ABC-DE+FG -A/B*C$DE Lecture 12, DCO20105, Semester A,2005-6 Examples of Postfix Expressions Infix Postfix A+B AB+ A+B-C (A+B)*(C-D) A$B*C-D+E/F/(G+H) ((A+B)*C-(D-E))$(F+G) A-B/(C*D$E) Rossella Lau AB+CAB+CD-* AB$C*D-EF/GH+/+ AB+C*DE--FG+$ ABCDE$*/- Lecture 12, DCO20105, Semester A,2005-6 Evaluating a postfix expression The advantage is no parentheses, i.e., less complication Since the operator comes later, operands can be pushed to the stack first and once an operator is encountered, the operands are popped for the calculation The algorithm (one digit operands) : Rossella Lau /* for one digit operands and no space in the expression */ int eval(string const & expr) { Stack<int> operands; for (size_t i=0; i<expr.size();i++){ char c = expr[i]; if (isdigit(c)) //operand operands.push((double)(c-'0'); else { // operator int operand2=operands.pop(); int operand1=operands.pop(); operands.push(cal (c, operand1, operand2)); } } return operands.top(); } Lecture 12, DCO20105, Semester A,2005-6 The algorithm for more than one digit double eval(string const & expr) { Stack<double> operands; char c, number[MAX]; size_t i, j=0; double num; for (i=0; i<expr.size(); i++) { c = expr[i]; if (isdigit(c) || c=='.') number[j++]=c; else { // a token is parsed if (j) ...... // convert number to num operands.push(num); if (c != ' ') { // operand ...... // pop, cal, and push }} } return operands.top(); } Rossella Lau ......//convert number to num number[j]='\0'; j=0; num = atof(number); ...... // pop, cal, and push double operand2 = operands.pop(); double operand1 = operands.pop(); operands.push(cal(c, operand1, operand2)); Lecture 12, DCO20105, Semester A,2005-6 cal(char, double, double) double cal(char oper, double op1,double op2) { switch (oper) { // “operator” is a key word case '+': return op1 + op2; case '-': return op1 - op2; case '*': return op1 * op2; case '/': return op1 / op2; case '$': return pow(op1,op2); default: // should not happen exit(EXIT_FAILURE); } } Rossella Lau Lecture 12, DCO20105, Semester A,2005-6 An example of postfix expression evaluation 4 57+* scan 457: push(4), push(5), push(7) scan +: op2=7, pop(), op1=5, pop(), push(op1+op2) scan *: op2=12, pop(), op1=4, pop(), push(op1*op2) expression end ==> return 48! Rossella Lau Lecture 12, DCO20105, Semester A,2005-6 Summary A stack It is one of the most basic data structures in the study. only has one end for insert and delete. An item in a stack is LIFO while it is FIFO in a queue Stack One An is used in many hidden areas of computer systems popular important application is expression evaluation expression can be in three forms: infix, prefix, and postfix It is common to evaluate an expression by using a postfix format Rossella Lau Lecture 12, DCO20105, Semester A,2005-6 Reference Ford: 7 Example programs: evaluateIntExpression.cpp, evaluateDoubleExpression.cpp STL online references http://www.sgi.com/tech/stl http://www.cppreference.com/ -- END -Rossella Lau Lecture 12, DCO20105, Semester A,2005-6