CSE 214 – Computer Science II Stack Applications Source: http://www.telusplanet.net/public/millsy/Games_win2k3.jpg
Why are stacks useful? They are good for solving particular types of problems 2 will look at today: the call stack evaluating arithmetic expressions
The Call Stack The Java Virtual Machine manages a Call Stack one for each thread actually When a method is called, a frame object is pushed onto that that thread’s Call Stack When a method returns, the top method is popped off that thread’s Call Stack
What’s a frame? Also called an activation record Has data for method call local variables & arguments Ex: public static void dummy(int num) { int sqr = num * num; String s = "sqr: "; printStuff(s + sqr); } dummy num (32 bits) s (32 bits) sqr (32 bits) s + sqr (32 bits)
Call Stack Example public static void main(String[] args) { int num1 = 5; dummy(num1); } public static void dummy(int num2) int sqr = num * num; String s = "sqr: "; printStuff(s + sqr); public static void printStuff(String n) System.out.println(n); main args num1 dummy num2 sqr s s + sqr printStuff n
Solve the following Now, let’s write a method that could solve this (((6 + 9)/3)*(6-4)) =((15/3)*(6-4)) =(5 * (6-4)) =(5 * 2) =10 Now, let’s write a method that could solve this Ex: int solveEquation(String equation) { …
How can we solve this? Using 2 steps 1st step: are parentheses balanced? if no, throw exception if yes, continue 2nd step: evaluate expression
public static int solveEquation(String equation) throws UnbalancedParenthesisException { if (areParenthesesBalanced(equation)) return evaluateExpression(equation); else throw new UnbalancedParenthesisException( "Unbalanced Parenthesis"); }
boolean areParenthesesBalanced(String exp) What should be the following output? String s1 = "(6 + 9)"; String s2 = "(6 + "; String s3 = "(6 + 9))"; boolean result; result = areParenthesesBalanced (s1); System.out.println(s1 + " is balanced: " + result + "\n"); result = areParenthesesBalanced (s2); System.out.println(s2 + " is balanced: " + result + "\n"); result = areParenthesesBalanced (s3); System.out.println(s3 + " is balanced: " + result); (6 + 9) is balanced: true (6 + is balanced: false (6 + 9)) is balanced: false
areParenthesesBalanced Let’s use a Stack to solve this problem How? examine all characters in expression, left to right if you find a ‘(‘, push it on the stack if you find a ‘)’, pop the stack If stack was empty, return 0 when done, if you have an empty stack, return 1 else return 0
public static boolean areParenthesesBalanced(String exp) { Stack<Character> stack = new Stack<Character>(); int i; boolean areBalanced; Object poppedData = null; char charToAdd; for (i = 0; i < exp.length(); i++) if (exp.charAt(i) == '(') stack.push('('); else if (exp.charAt(i) == ')') try{ poppedData = stack.pop(); } catch(EmptyStackException ese) return false; }
try { poppedData = stack try { poppedData = stack.pop(); return false; } catch(EmptyStackException ese) return true;
2nd step: evaluate expression How? Use 2 Stacks one for operators (+, -, *, /, etc.) one for operands (5, 6.2, etc.) Examine each character in the expression, left to right
Assumptions Fully parenthesized equations No foreign characters in expression to screw up number parsing let’s keep it simple Fully parenthesized equations matching ‘)’ for each operator this is ok: ((5 + (2 + 3))/10) this is not ok: (5 + (2 + 3)/10) Note: this is not the most robust approach in the world
Expression Examination When we find a: ‘(’ or ‘ ‘, do nothing ‘+’, ‘-’, ‘/’, or ‘*’, add it to the operator stack number, add it to the operand stack ‘)’: pop top operator pop top two operands evaluate expression using this data what do we do with the result? if we are at end of expression, return result else add result to operand stack
int evaluateExpression(String exp) What should be the following output? String e1 = "(((6 + 9)/3)*(6-4))"; String e2 = "(2 * (1024 / 16))"; String e3 = "((10 + ((100 * ((5 + 1) * (20 / (2 * 5)))) + (10 + 5)))/10)"; int num; num = evaluateExpression(e1); System.out.println(e1 + " = " + num); num = evaluateExpression(e2); System.out.println(e2 + " = " + num); num = evaluateExpression(e3); System.out.println(e3 + " = " + num); (((6 + 9)/3)*(6-4)) = 10 (6 / 3) = 2 ((10 + ((100 * ((5 + 1) * (20 / (2 * 5)))) + (10 + 5)))/10) = 122
public static int evaluateExpression(String exp) { Stack<Character> operators = new Stack<Character>(); Stack<Integer> operands = new Stack<Integer>(); int result, i; result = 0; for (i = 0; i < exp.length(); i++) char c = exp.charAt(i); if ((c == '(') || (c == ' ')) ; // DO NOTHING else if ((c == '+') || (c == '-') || (c == '*') || (c == '/')) operators.push(c);
else if (c == ')') { int operand1 = operands else if (c == ')') { int operand1 = operands.pop(); int operand2 = operands.pop(); char operator = operators.pop(); if (operator == '+') result = operand2 + operand1; else if (operator == '-') result = operand2 - operand1; else if (operator == '*') result = operand2 * operand1; else result = operand2 / operand1; if (i < (exp.length()-1)) operands.push(result); }
else { int j = i; while (Character. isDigit(exp else { int j = i; while (Character.isDigit(exp.charAt(j))) j++; String sub = exp.substring(i,j); int operandToAdd = Integer.parseInt(sub); operands.push(operandToAdd); i = j-1; } return result;
Other Stack Uses To Help Validate Source Code To Help Validate HTML match all parentheses, ( & ) match all brackets, { & } To Help Validate HTML match all < & > match all tags, i.e. <li> & </li>