370 likes | 566 Views
CSE 30331 Lecture 9 – Stacks, …. Stacks STL Stack Class Using a Stack to Convert number bases (dec2hex) Activation Records Mathematical Expressions Postfix Expressions Evaluating Postfix Infix Expressions Translating Infix to Postfix Maze Search Position Representing the maze
E N D
CSE 30331Lecture 9 – Stacks, … • Stacks • STL Stack Class • Using a Stack to Convert number bases (dec2hex) • Activation Records • Mathematical Expressions • Postfix Expressions • Evaluating Postfix • Infix Expressions • Translating Infix to Postfix • Maze Search • Position • Representing the maze • Algorithm using stack • Search Example
Stacks • A stack is a sequence of items that are accessible at only one end of the sequence.
Pushing/Popping a Stack • Because a pop removes the item last added to the stack, we say that a stack has LIFO (last-in/first-out) ordering.
CLASS stack CLASS stack <stack> <stack> Constructor Operations stack(); Create an empty stack bool empty(); const Check whether the stack is empty. Return true if it is empty and false otherwise.
CLASS stack <stack> Operations void pop(); Remove the item from the top of the stack. Precondition: The stack is not empty. Postcondition: Either the stack is empty or the stack has a new topmost item from a previous push. void push(const T& item); Insert the argument item at the top of the stack. Postcondition: The stack has a new item at the top.
CLASS stack <stack> Operations int size() const; Return the number of items on the stack. T& top() const; Return a reference to the value of the item at the top of the stack. Precondition: The stack is not empty. const T& top() const; Constant version of top().
STL stack class • stack<el_type, container_type> • Is an adapterclass • Possible containers are vector, list and deque • Uses size(), push_back(), pop_back(), back(), which are common to all containers • Default container is deque (best for large stacks that are frequently resized) • Vector is more efficient for small stacks • Examples: // int stack using stack<int> S1; // float stack using vector container stack<float, vector<float> > S2;
Decimal to base b conversion • Basic strategy n10 mb • While n not zero • Divide n by b quotient q and remainder r • Push remainder r onto stack • Set new value of n to q • While stack not empty • Output top value from stack • Pop stack
Decimal to base b string multibaseOutput (int num, int b) { string digitChar = “0123456789ABCDEF”, numStr = “”; stack<char> S; // compute remainders, dividing by b do { S.push(didigtChar[num % b]); // push remainder num = num / b; // find new quotient } while (num != 0); // reverse remainders on stack to obtain output while (! S.empty()) { numStr += S.top(); // append digit S.pop(); // pop from stack } return numStr; }
Activation Records • Each call to a function or entry of a block of code causes allocation of memory for the use of that block (its called an activation record) • Activation records contain space for … • Arguments in/out • Local variables (objects) • Return address
Factorial Arg (n) Return address (b) int fact(int n) { if (n == 1) return 1; return n*fact(n-1); } void main( ) { cout << fact(3); } Return address (a) fact(1) fact(2) fact(3)
Mathematical Expressions • Infix -- (left op right) • 6 + 3 • 3 + 5 * 1 / (3 + 1) • Postfix -- (left right op) • 6 3 + • 3 5 1 * 3 1 + / + • Stack is useful in evaluating postfix and in translating infix to postfix
Postfix Expression: 2 3 + • Push operand 2 on stack • Push operand 3 on stack • Detect + operator • Pop right operand 3 • Pop left operand 2 • Add operands • Push result 5 on stack
Postfix: 3 5 - 4 8 + * 2 - • Push 3 • Push 5 • Pop 5 and 3 to compute (3 – 5) and push -2 • Push 4 • Push 8 • Pop 8 and 4 to compute (4 + 8) and push 12 • Pop 12 and -2 to compute (-2 * 12) and push -24 • Push 2 • Pop 2 and -24 to compute (-24 – 2) and push -26 • Result (-26) is all that is left on stack
Evaluating Postfix(single digit operands only: no error checks) int evaluatePostFix(string expn) { int left, right, value; stack<int> operandStack; for (int i=0; i < expn.length(); i++) { char ch = expn[i]; if (isdigit(ch)) operandStack.push(ch - '0'); else if (isOperator(ch)) { getOperands(left, right); // pops stack twice // evaluate "left op right" and push result on stack operandStack.push(compute(left, right, ch)); } } value = operandStack.top(); // answer is on stack operandStack.pop(); return value; }
Converting infix to postfix9 - (2 + 3) * (8 - 5) = -6 • By hand ... • Add parentheses to infix expression to make explicit the order of evaluation • Start inside innermost parentheses and work your way out • At each level, convert ... • (val1 op val2) to (val1 val2 op) • Then drop all parentheses • Example: • 9 - (2 + 3) * (8 - 5) • (9 - ((2 + 3) * (8 - 5))) • (9 - ((2 3 +) * (8 5 -))) • (9 - ((2 3 +) (8 5 -) *)) • (9 ((2 3 +) (8 5 -) *) -) • 9 2 3 + 8 5 - * -
Infix to Postfix Algorithm While more input Read input symbol If it is an operand, write it to output Else if it is operator or “(“ While stack rank of S.top() >= input rank of operator Write S.top() to output Pop S Push input symbol onto stack Else if it is “)” While stack isn’t empty and S.top() != “(“ Write S.top() to output and Pop S Pop S to remove “(“ Flush the rest of the stack symbols to output
Precedence Symbol Input precedence Stack precedence Rank + - 1 1 -1 * / % 2 2 -1 ^ 4 3 -1 ( 5 -1 0 ) 0 0 0 Infix Expression Rules Input precedence, stack precedence, and rank used for the operators +, -, *, /, %, and ^, and parentheses. Except for the exponential operator ^, the other binary operators are left-associative and have equal input and stack precedence.
Knight’s Tour (revisited) • You found a recursive solution • Instead we can use a stack of all moves and possible alternative moves seen • Push start on stack and mark move # on board • Push all possible moves from here • While not failed and not foundSoln • If stack is empty we failed • Else If top of stack is posit of last move then foundSoln • Else If top of stack is available board posit • Mark move number on board and increment move # • Push all possible move posits from here • Else (we are backing up) • Mark board position as available again and decrement move # • Pop move posit from stack
2-D Maze Searching (depth-first) • Positions in maze are specified by posit • Posit is (row,col) pair • Maze representation is matrix of characters • ‘1’ = wall, • ‘0’ = open space, • ‘*’ = start, • ‘$’ = goal (finish) • File format for maze is • Row Col 4 7 • Data for 1st row 1$100*1 • Data for 2nd row 0010100 • Data for next row 0111010 • Data for last row 0000000 • With an implicit wall of 1’s all the way around
Maze at Start Possible next moves are stacked in this order N, S, E, W Start at p(7,1)
Maze Search • Stack of posits (locations) is used to keep track of progress of search • Each location that has been visited once and each possible move from such a location that is detected but not yet visited is pushed on the stack • When no forward motion is possible the stack is popped to move backward to old location where new move into unexplored location is possible
MazeSearch (depth first) • The maze matrix itself is modified to keep track of where we have been and what the status of a location is • Upon visiting a location these symbols are placed in the maze • ‘+’ = part of forward path, • ‘#’ = explored but led to dead end, • ‘~’ = detected but not explored • If search reaches goal, searcher isFree • If search returns to start, searcher isTrapped
Basic Search Algorithm set trapped and free to FALSE Find start, the posit of '*' Push start on stack Push adjacent posits (N,S,E,W) representing possible moves from start WHILE not trapped and not free DO make a move (detail on next slide) ENDWHILE IF trapped THEN write trapped message ELSE write out path from stack, reversing it
Make a Move Algorithm IF stack is empty, there are no more places to move Set trapped to TRUE ELSE, there are more places to move Set p to stack top posit, and pop stack If not at start or finish Show '?' on screen at position p, show we are here delay 1/4 second CASE maze[p] OF where are we? '*' : set maze[p] to '*' back at start '$' : set maze[p] to '$' at goal Push p to save present position set free to TRUE '~‘,'0' : set maze[p] to '+' moving forward show '+' at position p on screen Push p to save the position Push all potential moves (ap) from here Set each maze[ap] to '~' '+' : set maze[p] to '#' backing up show '#' at position p on screen ENDCASE
Maze at Start Possible next moves are stacked in this order N, S, E, W Start at p(7,1)
Maze at 1st dead end Possible next moves are stacked in this order N, S, E, W Dead end at p(8,6)
Maze at 2nd dead end Possible next moves are stacked in this order N, S, E, W Dead end at p(1,3)
Maze at 3rd dead end Possible next moves are stacked in this order N, S, E, W Dead end at p(1,1)
Maze at end of search Possible next moves are stacked in this order N, S, E, W Goal found at p(1,5)
Maze at end of search Stack 1,5 $ 2,5 + 2,6 + 2,8 ~~~~~ 1,7 ~~~~~ 2,7 + 3,7 + 4,7 + 4,8 + 5,8 + 6,8 + 6,7 + 7,6 ~~~~~ 6,6 + 6,5 + 5,4 ~~~~~ 6,4 + 6,3 + 7,3 + 8,3 + 8,2 + 8,1 + 6,1 ~~~~~ 7,1 *
Summary - Stack • Storage Structure with operations that occur only at one end, called the top of the stack • insert (push) • erase (pop) • The last element in is the first element out of the stack, so a stack is a LIFO structure.
Summary - Activation Records & the Runtime Stack • To support Recursion, the system maintains a stack of activation records that specify … • the function arguments • the local variables/objects • the return address • The system pushes an activation record when calling a function and pops it when returning.
Summary – Postfix Expressions • Postfix Expressions • Place the operator after its operands • Easy to evaluate using a single stack to hold operands. • The rules: • Immediately push an operand onto the stack. • For a binary operator, pop the stack twice, perform the operation, and push the result onto the stack. • At the end a single value remains on the stack. This is the value of the expression.
Summary – Infix expressions • Infix expressions • A binary operator appears between its operands. • More complex than postfix, because it requires the use of operator precedence and parentheses. • In addition, some operators are left-associative, and a few are right-associative.
Summary – Maze Searching • Maze Searching (depth-first) • Stack used to hold positions visited and those detected but not yet visited. • At end of search, empty stack means no way out, non-empty stack contains path from start to finish (in reverse order) • Stack also contains potential move locations that were never pursued. These must be removed during path recovery.