Applications of Stack
1. Recursive Procedures
To see how a stack can be used to implement recursive procedures in a non-recursive way, we take Hanoi Tower Problem for example:
1 public class Main { 2 public static class Hanoi { 3 public int start; 4 public int dest; 5 public int num; 6 7 public Hanoi(int start,int dest,int num) { 8 this.start = start; 9 this.dest = dest; 10 this.num = num; 11 } 12 public String toString() { 13 return "Move from "+printStack(start)+" to "+printStack(dest); 14 } 15 private String printStack(int idx) { 16 switch (idx) { 17 case 0: return "A"; 18 case 1: return "B"; 19 case 2: return "C"; 20 default: 21 return null; 22 } 23 } 24 } 25 public static void main(String[] args) { 26 Scanner in = new Scanner(System.in); 27 Stack<Hanoi> stack = new Stack<Hanoi>(); 28 System.out.print("Input the number of disks:\n\t"); 29 stack.push(new Hanoi(0,2,in.nextInt())); 30 while (!stack.isEmpty()) { 31 Hanoi h = stack.pop(); 32 if (h.num==1) { 33 System.out.println(h); 34 } else { 35 int tmp = 3-h.start-h.dest; 36 stack.push(new Hanoi(tmp,h.dest,h.num-1)); 37 stack.push(new Hanoi(h.start,h.dest,1)); 38 stack.push(new Hanoi(h.start,tmp,h.num-1)); 39 } 40 } 41 in.close(); 42 } 43 }
2. Event-Driven Simulation
Similar to queues, stacks are also widely used in event-driven simulations. Here, I cite an example from SJTU ACM Online Judge:
1 import java.util.*; 2 3 public class Main { 4 public static int [] arr; 5 6 public static boolean test(int num,int size) { 7 Stack<Integer> stack = new Stack<Integer>(); 8 int come = 0; // the number of a coming train 9 for (int i=0;i<num;i++) { 10 // For each loop, a desired train departs from the station 11 if (!stack.isEmpty() &&arr[i]==stack.peek().intValue()) { 12 // first, consider the top of the stack 13 stack.pop(); 14 size++; 15 continue; 16 } 17 while (arr[i]!=come++) { 18 // next, look forward to a new-comer 19 if (come==num) { 20 // no more new-comers 21 return false; 22 } 23 stack.push(new Integer(come-1)); 24 if (--size<0) { 25 // no space for new-comers 26 return false; 27 } 28 } 29 } 30 return true; 31 } 32 public static void main(String[] args) { 33 Scanner in = new Scanner(System.in); 34 int testNum = in.nextInt(); 35 arr = new int [1024]; 36 for (int i=0;i<testNum;i++) { 37 int num = in.nextInt(); 38 int size = in.nextInt(); 39 for (int j=0;j<num;j++) { 40 arr[j] = in.nextInt(); 41 } 42 if (test(num,size)) { 43 System.out.println("YES"); 44 } else { 45 System.out.println("NO"); 46 } 47 } 48 in.close(); 49 } 50 }
3. Infix Expression Calculation
This program first converts an infix expression into a suffix expression with the help of an operator stack, and then calculates the suffix expression by using an operand stack.
Sample Input and Output:
1 import java.util.*; 2 import java.io.*; 3 4 class Suffix { 5 private Stack<Integer> stack; 6 7 public Suffix() { 8 stack = new Stack<Integer>(); 9 } 10 public void addToken(String str) { 11 if (str.equals("+") || str.equals("-") || str.equals("*") || 12 str.equals("/") || str.equals("^")) { 13 int b = stack.pop().intValue(); 14 int a = stack.pop().intValue(); 15 if (str.equals("+")) { 16 stack.add(new Integer(a+b)); 17 } else if (str.equals("-")) { 18 stack.add(new Integer(a-b)); 19 } else if (str.equals("*")) { 20 stack.add(new Integer(a*b)); 21 } else if (str.equals("/")) { 22 stack.add(new Integer(a/b)); 23 } else { 24 int val = 1; 25 for (int i=0;i<b;i++) { 26 val *= a; 27 } 28 stack.add(new Integer(val)); 29 } 30 } else { // an operand 31 stack.add(Integer.valueOf(str)); 32 } 33 } 34 public int getVal() { 35 return stack.peek().intValue(); 36 } 37 public void clear() { 38 stack.clear(); 39 } 40 } 41 42 public class InfixExpr { 43 private static BufferedReader in; 44 private static StringTokenizer tokenizer; 45 private static Stack<String> stack; 46 private static Suffix server; 47 48 private static void printAndCal(String expr) { 49 System.out.println(expr); 50 tokenizer = new StringTokenizer(expr); 51 // ATTENTION: we can't use a for-loop based on 52 // tokenizer.countTokens() since it is mutable 53 while (tokenizer.hasMoreTokens()){ 54 String str = tokenizer.nextToken(); 55 if (str.equals("(")) { 56 stack.add(str); 57 } else if (str.equals(")")) { 58 String op = stack.pop(); 59 while (!op.equals("(")) { 60 server.addToken(op); 61 op = stack.pop(); 62 } 63 } else if (str.equals("+") || str.equals("-") || str.equals("*") || 64 str.equals("/") || str.equals("^")) { 65 while (!stack.isEmpty()&&!stack.peek().equals("(")&&prior(stack.peek(),str)) { 66 server.addToken(stack.pop()); 67 } 68 stack.add(str); 69 } else { // an operand 70 server.addToken(str); 71 } 72 } 73 while (!stack.isEmpty()) { 74 server.addToken(stack.pop()); 75 } 76 System.out.println(server.getVal()); 77 } 78 private static boolean prior(String op1,String op2) { 79 // Returns whether op1 can be operated first when 80 // it is aligned with operator op2 81 if (op2.equals("^")) { 82 return false; 83 } else if (op2.equals("*")||op2.equals("/")) { 84 return !op1.equals("+")&&!op1.equals("-"); 85 } else { 86 return true; 87 } 88 } 89 public static void main(String[] args) throws IOException { 90 in = new BufferedReader(new FileReader("infix.in")); 91 stack = new Stack<String>(); 92 server = new Suffix(); 93 int n = Integer.parseInt(in.readLine()); 94 System.out.println(n); 95 for (int i=0;i<n;i++) { 96 server.clear(); 97 printAndCal(in.readLine()); 98 } 99 in.close(); 100 } 101 }