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 }

 

posted on 2015-04-12 13:20  DevinZ  阅读(166)  评论(0编辑  收藏  举报

导航